X-Git-Url: https://git.saurik.com/apple/configd.git/blobdiff_plain/9de8ab86392ba34369adc6be0bfc21bad9b7caa2..6de80e47cd0fa121e11fcedf2e472e13c2f8ea0e:/IPMonitorControl/IPMonitorControlServer.c diff --git a/IPMonitorControl/IPMonitorControlServer.c b/IPMonitorControl/IPMonitorControlServer.c index 53ad39d..cbdd9dc 100644 --- a/IPMonitorControl/IPMonitorControlServer.c +++ b/IPMonitorControl/IPMonitorControlServer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015 Apple Inc. All rights reserved. + * Copyright (c) 2013-2018 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -40,13 +40,14 @@ #include #include #include +#include #include "IPMonitorControlServer.h" #include "symbol_scope.h" #include "IPMonitorControlPrivate.h" -#include +#include "IPMonitorAWDReport.h" #ifdef TEST_IPMONITOR_CONTROL -#define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__) +#define my_log(__level, __format, ...) SCPrint(TRUE, stdout, CFSTR(__format "\n"), ## __VA_ARGS__) #else /* TEST_IPMONITOR_CONTROL */ #include "ip_plugin.h" @@ -63,7 +64,9 @@ LIST_HEAD_ControlSession S_ControlSessions; struct ControlSession { LIST_ENTRY_ControlSession link; xpc_connection_t connection; + CFMutableDictionaryRef assertions; /* ifname = rank */ + CFMutableDictionaryRef advisories; /* ifname = advisory */ }; /** @@ -72,6 +75,20 @@ struct ControlSession { STATIC CFMutableArrayRef S_if_changes; STATIC CFRange S_if_changes_range; +STATIC CFNumberRef +RankLastNumberGet(void) +{ + STATIC CFNumberRef rank_last; + + if (rank_last == NULL) { + SCNetworkServicePrimaryRank rank; + + rank = kSCNetworkServicePrimaryRankLast; + rank_last = CFNumberCreate(NULL, kCFNumberSInt32Type, &rank); + } + return (rank_last); +} + STATIC void InterfaceChangedListAddInterface(CFStringRef ifname) { @@ -81,8 +98,7 @@ InterfaceChangedListAddInterface(CFStringRef ifname) CFArrayAppendValue(S_if_changes, ifname); S_if_changes_range.length = 1; } - else if (CFArrayContainsValue(S_if_changes, S_if_changes_range, - ifname) == FALSE) { + else if (!CFArrayContainsValue(S_if_changes, S_if_changes_range, ifname)) { CFArrayAppendValue(S_if_changes, ifname); S_if_changes_range.length++; } @@ -111,14 +127,42 @@ InterfaceRankAssertionAdd(const void * key, const void * value, void * context) = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(*assertions_p, key, value); + CFDictionarySetValue(*assertions_p, key, rank); return; } existing_rank = CFDictionaryGetValue(*assertions_p, key); if (existing_rank == NULL || (CFNumberCompare(rank, existing_rank, NULL) == kCFCompareGreaterThan)) { - CFDictionarySetValue(*assertions_p, key, value); + CFDictionarySetValue(*assertions_p, key, rank); + } + return; +} + +STATIC void +InterfaceAdvisoryAdd(const void * key, const void * value, void * context) +{ +#pragma unused(value) + CFMutableDictionaryRef * assertions_p; + CFNumberRef existing_rank; + CFNumberRef rank; + + /* an interface advisory implies RankLast */ + rank = RankLastNumberGet(); + assertions_p = (CFMutableDictionaryRef *)context; + if (*assertions_p == NULL) { + *assertions_p + = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(*assertions_p, key, rank); + return; + } + existing_rank = CFDictionaryGetValue(*assertions_p, key); + if (existing_rank == NULL + || (CFNumberCompare(rank, existing_rank, NULL) + == kCFCompareGreaterThan)) { + CFDictionarySetValue(*assertions_p, key, rank); } return; } @@ -130,16 +174,101 @@ InterfaceRankAssertionsCopy(void) ControlSessionRef session; LIST_FOREACH(session, &S_ControlSessions, link) { - if (session->assertions == NULL) { - continue; + if (session->advisories != NULL) { + CFDictionaryApplyFunction(session->advisories, + InterfaceAdvisoryAdd, + &assertions); + } + if (session->assertions != NULL) { + CFDictionaryApplyFunction(session->assertions, + InterfaceRankAssertionAdd, + &assertions); } - CFDictionaryApplyFunction(session->assertions, - InterfaceRankAssertionAdd, - &assertions); } return (assertions); } +STATIC Boolean +InterfaceHasAdvisories(CFStringRef ifname) +{ + ControlSessionRef session; + + LIST_FOREACH(session, &S_ControlSessions, link) { + if (session->advisories != NULL + && CFDictionaryContainsKey(session->advisories, ifname)) { + return (TRUE); + } + } + return (FALSE); +} + + +STATIC AWDIPMonitorInterfaceAdvisoryReport_Flags +advisory_to_flags(SCNetworkInterfaceAdvisory advisory) +{ + AWDIPMonitorInterfaceAdvisoryReport_Flags flags; + + switch (advisory) { + case kSCNetworkInterfaceAdvisoryNone: + default: + flags = 0; + break; + case kSCNetworkInterfaceAdvisoryLinkLayerIssue: + flags = AWDIPMonitorInterfaceAdvisoryReport_Flags_LINK_LAYER_ISSUE; + break; + case kSCNetworkInterfaceAdvisoryUplinkIssue: + flags = AWDIPMonitorInterfaceAdvisoryReport_Flags_UPLINK_ISSUE; + break; + } + return (flags); +} + +STATIC AWDIPMonitorInterfaceAdvisoryReport_Flags +InterfaceGetAdvisoryFlags(CFStringRef ifname, + ControlSessionRef exclude_session, + uint32_t * ret_count) +{ + uint32_t count; + AWDIPMonitorInterfaceAdvisoryReport_Flags flags = 0; + ControlSessionRef session; + + count = 0; + LIST_FOREACH(session, &S_ControlSessions, link) { + SCNetworkInterfaceAdvisory advisory = 0; + CFNumberRef advisory_cf; + + if (session->advisories == NULL) { + continue; + } + if (exclude_session != NULL && exclude_session == session) { + continue; + } + advisory_cf = CFDictionaryGetValue(session->advisories, ifname); + if (advisory_cf == NULL) { + /* session has no advisories for this interface */ + continue; + } + (void)CFNumberGetValue(advisory_cf, kCFNumberSInt32Type, &advisory); + flags |= advisory_to_flags(advisory); + count++; + } + *ret_count = count; + return (flags); +} + +STATIC Boolean +AnyInterfaceHasAdvisories(void) +{ + ControlSessionRef session; + + LIST_FOREACH(session, &S_ControlSessions, link) { + if (session->advisories != NULL) { + return (TRUE); + } + } + return (FALSE); +} + STATIC CFRunLoopRef S_runloop; STATIC CFRunLoopSourceRef S_signal_source; @@ -152,7 +281,7 @@ SetNotificationInfo(CFRunLoopRef runloop, CFRunLoopSourceRef rls) } STATIC void -GenerateNotification(void) +NotifyIPMonitor(void) { if (S_signal_source != NULL) { CFRunLoopSourceSignal(S_signal_source); @@ -163,32 +292,128 @@ GenerateNotification(void) return; } +STATIC void +NotifyInterfaceAdvisory(CFStringRef ifname) +{ + CFStringRef key; + + key = _IPMonitorControlCopyInterfaceAdvisoryNotificationKey(ifname); + SCDynamicStoreNotifyValue(NULL, key); + CFRelease(key); + return; +} + +STATIC void +SubmitInterfaceAdvisoryMetric(CFStringRef ifname, + AWDIPMonitorInterfaceAdvisoryReport_Flags flags, + uint32_t count) +{ + InterfaceAdvisoryReportRef report; + AWDIPMonitorInterfaceType type; + + /* XXX need to actually figure out what the interface type is */ + if (CFStringHasPrefix(ifname, CFSTR("pdp"))) { + type = AWDIPMonitorInterfaceType_IPMONITOR_INTERFACE_TYPE_CELLULAR; + } + else { + type = AWDIPMonitorInterfaceType_IPMONITOR_INTERFACE_TYPE_WIFI; + } + report = InterfaceAdvisoryReportCreate(type); + if (report == NULL) { + return; + } + InterfaceAdvisoryReportSetFlags(report, flags); + InterfaceAdvisoryReportSetAdvisoryCount(report, count); + InterfaceAdvisoryReportSubmit(report); + my_log(LOG_NOTICE, "%@: submitted AWD report %@", ifname, report); + CFRelease(report); +} + /** ** ControlSession **/ STATIC void AddChangedInterface(const void * key, const void * value, void * context) { +#pragma unused(value) +#pragma unused(context) + InterfaceChangedListAddInterface((CFStringRef)key); + return; +} + +STATIC void +AddChangedInterfaceNotify(const void * key, const void * value, void * context) +{ +#pragma unused(value) +#pragma unused(context) InterfaceChangedListAddInterface((CFStringRef)key); + NotifyInterfaceAdvisory((CFStringRef)key); return; } +STATIC void +GenerateMetricForInterfaceAtSessionClose(const void * key, const void * value, + void * context) +{ + uint32_t count_after; + uint32_t count_before; + AWDIPMonitorInterfaceAdvisoryReport_Flags flags_after; + AWDIPMonitorInterfaceAdvisoryReport_Flags flags_before; + CFStringRef ifname = (CFStringRef)key; + ControlSessionRef session = (ControlSessionRef)context; + +#pragma unused(value) + /* + * Get the flags and count including this session, then again + * excluding this session. If either flags or count are different, + * generate the metric. + */ + flags_before = InterfaceGetAdvisoryFlags(ifname, NULL, &count_before); + flags_after = InterfaceGetAdvisoryFlags(ifname, session, &count_after); + if (flags_before != flags_after || count_before != count_after) { + SubmitInterfaceAdvisoryMetric(ifname, flags_after, count_after); + } + return; +} + +STATIC void +ControlSessionGenerateMetricsAtClose(ControlSessionRef session) +{ + if (session->advisories == NULL) { + return; + } + CFDictionaryApplyFunction(session->advisories, + GenerateMetricForInterfaceAtSessionClose, + session); +} + STATIC void ControlSessionInvalidate(ControlSessionRef session) { my_log(LOG_DEBUG, "Invalidating %p", session); + ControlSessionGenerateMetricsAtClose(session); LIST_REMOVE(session, link); - if (session->assertions != NULL) { - my_log(LOG_DEBUG, - "IPMonitorControlServer: %p pid %d removing assertions %@", - session->connection, - xpc_connection_get_pid(session->connection), - session->assertions); - CFDictionaryApplyFunction(session->assertions, AddChangedInterface, - NULL); - CFRelease(session->assertions); - session->assertions = NULL; - GenerateNotification(); + if (session->assertions != NULL || session->advisories != NULL) { + if (session->advisories != NULL) { + my_log(LOG_NOTICE, + "pid %d removing advisories %@", + xpc_connection_get_pid(session->connection), + session->advisories); + CFDictionaryApplyFunction(session->advisories, + AddChangedInterfaceNotify, + NULL); + my_CFRelease(&session->advisories); + } + if (session->assertions != NULL) { + my_log(LOG_NOTICE, + "pid %d removing assertions %@", + xpc_connection_get_pid(session->connection), + session->assertions); + CFDictionaryApplyFunction(session->assertions, AddChangedInterface, + NULL); + my_CFRelease(&session->assertions); + } + NotifyIPMonitor(); } return; } @@ -213,7 +438,7 @@ ControlSessionCreate(xpc_connection_t connection) ControlSessionRef session; session = (ControlSessionRef)malloc(sizeof(*session)); - bzero(session, sizeof(*session)); + memset(session, 0, sizeof(*session)); session->connection = connection; xpc_connection_set_finalizer_f(connection, ControlSessionRelease); xpc_connection_set_context(connection, session); @@ -223,7 +448,7 @@ ControlSessionCreate(xpc_connection_t connection) } STATIC ControlSessionRef -ControlSessionGet(xpc_connection_t connection) +ControlSessionForConnection(xpc_connection_t connection) { ControlSessionRef session; @@ -269,7 +494,7 @@ ControlSessionSetInterfaceRank(ControlSessionRef session, CFRelease(rank_cf); } InterfaceChangedListAddInterface(ifname_cf); - GenerateNotification(); + NotifyIPMonitor(); CFRelease(ifname_cf); return; } @@ -295,11 +520,75 @@ ControlSessionGetInterfaceRank(ControlSessionRef session, return (rank); } +STATIC void +ControlSessionSetInterfaceAdvisory(ControlSessionRef session, + const char * ifname, + SCNetworkInterfaceAdvisory advisory) +{ + uint32_t count_after; + uint32_t count_before; + AWDIPMonitorInterfaceAdvisoryReport_Flags flags_after; + AWDIPMonitorInterfaceAdvisoryReport_Flags flags_before; + CFStringRef ifname_cf; + + if (session->advisories == NULL) { + if (advisory == kSCNetworkInterfaceAdvisoryNone) { + /* no advisories, no need to store advisory */ + return; + } + session->advisories + = CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + } + ifname_cf = CFStringCreateWithCString(NULL, ifname, + kCFStringEncodingUTF8); + flags_before = InterfaceGetAdvisoryFlags(ifname_cf, NULL, &count_before); + if (advisory == kSCNetworkInterfaceAdvisoryNone) { + CFDictionaryRemoveValue(session->advisories, ifname_cf); + if (CFDictionaryGetCount(session->advisories) == 0) { + CFRelease(session->advisories); + session->advisories = NULL; + } + } + else { + CFNumberRef advisory_cf; + + advisory_cf = CFNumberCreate(NULL, kCFNumberSInt32Type, &advisory); + CFDictionarySetValue(session->advisories, ifname_cf, advisory_cf); + CFRelease(advisory_cf); + } + flags_after = InterfaceGetAdvisoryFlags(ifname_cf, NULL, &count_after); + if (flags_before != flags_after || count_before != count_after) { + SubmitInterfaceAdvisoryMetric(ifname_cf, flags_after, count_after); + } + InterfaceChangedListAddInterface(ifname_cf); + NotifyInterfaceAdvisory(ifname_cf); + NotifyIPMonitor(); + CFRelease(ifname_cf); + return; +} + /** ** IPMonitorControlServer **/ + +STATIC const char * +get_process_name(xpc_object_t request) +{ + const char * process_name; + + process_name + = xpc_dictionary_get_string(request, + kIPMonitorControlRequestKeyProcessName); + if (process_name == NULL) { + process_name = ""; + } + return (process_name); +} + STATIC Boolean -IPMonitorControlServerValidateConnection(xpc_connection_t connection) +IPMonitorControlServerConnectionIsRoot(xpc_connection_t connection) { uid_t uid; @@ -307,16 +596,62 @@ IPMonitorControlServerValidateConnection(xpc_connection_t connection) return (uid == 0); } +STATIC Boolean +IPMonitorControlServerConnectionHasEntitlement(xpc_connection_t connection, + const char * entitlement) +{ + Boolean entitled = FALSE; + xpc_object_t val; + + val = xpc_connection_copy_entitlement_value(connection, entitlement); + if (val != NULL) { + if (xpc_get_type(val) == XPC_TYPE_BOOL) { + entitled = xpc_bool_get_value(val); + } + xpc_release(val); + } + return (entitled); +} + +STATIC const char * +get_rank_str(SCNetworkServicePrimaryRank rank) +{ + const char * str = NULL; + + switch (rank) { + case kSCNetworkServicePrimaryRankDefault: + str = "Default"; + break; + case kSCNetworkServicePrimaryRankFirst: + str = "First"; + break; + case kSCNetworkServicePrimaryRankLast: + str = "Last"; + break; + case kSCNetworkServicePrimaryRankNever: + str = "Never"; + break; + case kSCNetworkServicePrimaryRankScoped: + str = "Scoped"; + break; + default: + break; + } + return (str); +} + STATIC int -IPMonitorControlServerHandleSetInterfaceRank(xpc_connection_t connection, - xpc_object_t request, - xpc_object_t reply) +HandleSetInterfaceRank(xpc_connection_t connection, + xpc_object_t request, + xpc_object_t reply) { +#pragma unused(reply) const char * ifname; SCNetworkServicePrimaryRank rank; + const char * rank_str; ControlSessionRef session; - if (IPMonitorControlServerValidateConnection(connection) == FALSE) { + if (!IPMonitorControlServerConnectionIsRoot(connection)) { my_log(LOG_INFO, "connection %p pid %d permission denied", connection, xpc_connection_get_pid(connection)); return (EPERM); @@ -330,27 +665,22 @@ IPMonitorControlServerHandleSetInterfaceRank(xpc_connection_t connection, rank = (SCNetworkServicePrimaryRank) xpc_dictionary_get_uint64(request, kIPMonitorControlRequestKeyPrimaryRank); - switch (rank) { - case kSCNetworkServicePrimaryRankDefault: - case kSCNetworkServicePrimaryRankFirst: - case kSCNetworkServicePrimaryRankLast: - case kSCNetworkServicePrimaryRankNever: - case kSCNetworkServicePrimaryRankScoped: - break; - default: + rank_str = get_rank_str(rank); + if (rank_str == NULL) { return (EINVAL); } - session = ControlSessionGet(connection); + session = ControlSessionForConnection(connection); ControlSessionSetInterfaceRank(session, ifname, rank); - my_log(LOG_INFO, "connection %p pid %d set %s %u", - connection, xpc_connection_get_pid(connection), ifname, rank); + my_log(LOG_NOTICE, "%s[%d] SetInterfaceRank(%s) = %s (%u)", + get_process_name(request), + xpc_connection_get_pid(connection), ifname, rank_str, rank); return (0); } STATIC int -IPMonitorControlServerHandleGetInterfaceRank(xpc_connection_t connection, - xpc_object_t request, - xpc_object_t reply) +HandleGetInterfaceRank(xpc_connection_t connection, + xpc_object_t request, + xpc_object_t reply) { const char * ifname; SCNetworkServicePrimaryRank rank; @@ -377,12 +707,125 @@ IPMonitorControlServerHandleGetInterfaceRank(xpc_connection_t connection, return (0); } +STATIC const char * +get_advisory_str(SCNetworkInterfaceAdvisory advisory) +{ + const char * str = NULL; + + switch (advisory) { + case kSCNetworkInterfaceAdvisoryNone: + str = "None"; + break; + case kSCNetworkInterfaceAdvisoryLinkLayerIssue: + str = "LinkLayerIssue"; + break; + case kSCNetworkInterfaceAdvisoryUplinkIssue: + str = "UplinkIssue"; + break; + default: + break; + } + return (str); +} + +STATIC int +HandleSetInterfaceAdvisory(xpc_connection_t connection, + xpc_object_t request, + xpc_object_t reply) +{ +#pragma unused(reply) + SCNetworkInterfaceAdvisory advisory; + const char * advisory_str; + const char * ifname; + const char * reason; + ControlSessionRef session; + +#define ENTITLEMENT "com.apple.SystemConfiguration.SCNetworkInterfaceSetAdvisory" + if (!IPMonitorControlServerConnectionIsRoot(connection) + && !IPMonitorControlServerConnectionHasEntitlement(connection, + ENTITLEMENT)) { + my_log(LOG_INFO, "connection %p pid %d permission denied", + connection, xpc_connection_get_pid(connection)); + return (EPERM); + } + ifname + = xpc_dictionary_get_string(request, + kIPMonitorControlRequestKeyInterfaceName); + if (ifname == NULL) { + return (EINVAL); + } + reason + = xpc_dictionary_get_string(request, + kIPMonitorControlRequestKeyReason); + advisory = (SCNetworkInterfaceAdvisory) + xpc_dictionary_get_uint64(request, kIPMonitorControlRequestKeyAdvisory); + + /* validate the advisory code */ + advisory_str = get_advisory_str(advisory); + if (advisory_str == NULL) { + return (EINVAL); + } + session = ControlSessionForConnection(connection); + ControlSessionSetInterfaceAdvisory(session, ifname, advisory); + my_log(LOG_NOTICE, "%s[%d] SetInterfaceAdvisory(%s) = %s (%u) reason='%s'", + get_process_name(request), + xpc_connection_get_pid(connection), ifname, advisory_str, advisory, + reason != NULL ? reason : "" ); + return (0); +} + +STATIC int +HandleInterfaceAdvisoryIsSet(xpc_connection_t connection, + xpc_object_t request, + xpc_object_t reply) +{ +#pragma unused(connection) + const char * ifname; + CFStringRef ifname_cf; + + if (reply == NULL) { + /* no point in processing the request if we can't provide an answer */ + return (EINVAL); + } + ifname + = xpc_dictionary_get_string(request, + kIPMonitorControlRequestKeyInterfaceName); + if (ifname == NULL) { + return (EINVAL); + } + ifname_cf = CFStringCreateWithCString(NULL, ifname, + kCFStringEncodingUTF8); + xpc_dictionary_set_bool(reply, + kIPMonitorControlResponseKeyAdvisoryIsSet, + InterfaceHasAdvisories(ifname_cf)); + CFRelease(ifname_cf); + return (0); +} + +STATIC int +HandleAnyInterfaceAdvisoryIsSet(xpc_connection_t connection, + xpc_object_t request, + xpc_object_t reply) +{ +#pragma unused(connection) +#pragma unused(request) + if (reply == NULL) { + /* no point in processing the request if we can't provide an answer */ + return (EINVAL); + } + xpc_dictionary_set_bool(reply, + kIPMonitorControlResponseKeyAdvisoryIsSet, + AnyInterfaceHasAdvisories()); + return (0); +} + STATIC void IPMonitorControlServerHandleDisconnect(xpc_connection_t connection) { ControlSessionRef session; - my_log(LOG_DEBUG, "IPMonitorControlServer: client %p went away", connection); + my_log(LOG_DEBUG, "IPMonitorControlServer: client %p went away", + connection); session = ControlSessionLookup(connection); if (session == NULL) { /* never asserted anything */ @@ -411,14 +854,19 @@ IPMonitorControlServerHandleRequest(xpc_connection_t connection, reply = xpc_dictionary_create_reply(request); switch (request_type) { case kIPMonitorControlRequestTypeSetInterfaceRank: - error = IPMonitorControlServerHandleSetInterfaceRank(connection, - request, - reply); + error = HandleSetInterfaceRank(connection, request, reply); break; case kIPMonitorControlRequestTypeGetInterfaceRank: - error = IPMonitorControlServerHandleGetInterfaceRank(connection, - request, - reply); + error = HandleGetInterfaceRank(connection, request, reply); + break; + case kIPMonitorControlRequestTypeSetInterfaceAdvisory: + error = HandleSetInterfaceAdvisory(connection, request, reply); + break; + case kIPMonitorControlRequestTypeInterfaceAdvisoryIsSet: + error = HandleInterfaceAdvisoryIsSet(connection, request, reply); + break; + case kIPMonitorControlRequestTypeAnyInterfaceAdvisoryIsSet: + error = HandleAnyInterfaceAdvisoryIsSet(connection, request, reply); break; default: error = EINVAL; @@ -454,16 +902,10 @@ IPMonitorControlServerHandleNewConnection(xpc_connection_t connection) xpc_handler_t handler; handler = ^(xpc_object_t event) { - os_activity_t activity_id; - - activity_id = os_activity_start("processing IPMonitor [rank] request", - OS_ACTIVITY_FLAG_DEFAULT); - IPMonitorControlServerHandleRequest(connection, event); - - os_activity_end(activity_id); }; xpc_connection_set_event_handler(connection, handler); + xpc_connection_set_target_queue(connection, S_IPMonitorControlServerQueue); xpc_connection_resume(connection); return; } @@ -480,12 +922,8 @@ IPMonitorControlServerCreate(dispatch_queue_t queue, const char * name) return (NULL); } handler = ^(xpc_object_t event) { - os_activity_t activity_id; xpc_type_t type; - activity_id = os_activity_start("processing IPMonitor [rank] connection request", - OS_ACTIVITY_FLAG_DEFAULT); - type = xpc_get_type(event); if (type == XPC_TYPE_CONNECTION) { IPMonitorControlServerHandleNewConnection(event); @@ -505,8 +943,6 @@ IPMonitorControlServerCreate(dispatch_queue_t queue, const char * name) else { my_log(LOG_NOTICE, "unknown event %p", type); } - - os_activity_end(activity_id); }; S_IPMonitorControlServerQueue = queue; xpc_connection_set_event_handler(connection, handler); @@ -518,6 +954,7 @@ PRIVATE_EXTERN Boolean IPMonitorControlServerStart(CFRunLoopRef runloop, CFRunLoopSourceRef rls, Boolean * verbose) { +#pragma unused(verbose) dispatch_queue_t q; xpc_connection_t connection;