summaryrefslogtreecommitdiffstats
path: root/mDNSResponder
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:57:22 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:34 +0200
commit272360946778648e9090941ad1aa43b60d5031a3 (patch)
tree89ba96a3f9d797190a8d423232f1c04c3d0c8432 /mDNSResponder
parentmDNSResponder: Update to v878.20.3 (diff)
downloadrtems-libbsd-272360946778648e9090941ad1aa43b60d5031a3.tar.bz2
mDNSResponder: Update to v878.30.4
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-878.30.4.tar.gz Close #3522.
Diffstat (limited to 'mDNSResponder')
-rw-r--r--mDNSResponder/Makefile2
-rwxr-xr-xmDNSResponder/mDNSCore/mDNS.c15
-rwxr-xr-xmDNSResponder/mDNSCore/mDNSEmbeddedAPI.h6
-rwxr-xr-xmDNSResponder/mDNSCore/uDNS.c15
-rw-r--r--mDNSResponder/mDNSMacOSX/Metrics.h18
-rw-r--r--mDNSResponder/mDNSMacOSX/Metrics.m973
-rw-r--r--mDNSResponder/mDNSMacOSX/daemon.c33
-rw-r--r--mDNSResponder/mDNSMacOSX/helper.c19
-rw-r--r--mDNSResponder/mDNSMacOSX/mDNSMacOSX.c54
-rw-r--r--mDNSResponder/mDNSShared/dns_sd.h2
10 files changed, 782 insertions, 355 deletions
diff --git a/mDNSResponder/Makefile b/mDNSResponder/Makefile
index 1c7c63ac..9d975334 100644
--- a/mDNSResponder/Makefile
+++ b/mDNSResponder/Makefile
@@ -16,7 +16,7 @@
include $(MAKEFILEPATH)/pb_makefiles/platform.make
-MVERS = "mDNSResponder-878.20.3"
+MVERS = "mDNSResponder-878.30.4"
VER =
ifneq ($(strip $(GCC_VERSION)),)
diff --git a/mDNSResponder/mDNSCore/mDNS.c b/mDNSResponder/mDNSCore/mDNS.c
index 0d4d8ae4..72375d94 100755
--- a/mDNSResponder/mDNSCore/mDNS.c
+++ b/mDNSResponder/mDNSCore/mDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -4170,12 +4170,12 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
responseLatencyMs = 0;
}
- MetricsUpdateUDNSQueryStats(queryName, q->qtype, &rr->resrec, q->metrics.querySendCount, responseLatencyMs, isForCellular);
+ MetricsUpdateDNSQueryStats(queryName, q->qtype, &rr->resrec, q->metrics.querySendCount, responseLatencyMs, isForCellular);
q->metrics.answered = mDNStrue;
}
if (q->metrics.querySendCount > 0)
{
- MetricsUpdateUDNSResolveStats(queryName, &rr->resrec, isForCellular);
+ MetricsUpdateDNSResolveStats(queryName, &rr->resrec, isForCellular);
}
}
#endif
@@ -8944,6 +8944,13 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
response->h.numAuthorities, response->h.numAuthorities == 1 ? "y, " : "ies,",
response->h.numAdditionals, response->h.numAdditionals == 1 ? " " : "s", end - response->data, LLQType);
+#if AWD_METRICS
+ if (mDNSSameIPPort(srcport, UnicastDNSPort))
+ {
+ MetricsUpdateDNSResponseSize((mDNSu32)(end - (mDNSu8 *)response));
+ }
+#endif
+
// According to RFC 2181 <http://www.ietf.org/rfc/rfc2181.txt>
// When a DNS client receives a reply with TC
// set, it should ignore that response, and query again, using a
@@ -12127,7 +12134,7 @@ mDNSexport mStatus mDNS_StopQuery_internal(mDNS *const m, DNSQuestion *const que
queryName = question->metrics.originalQName ? question->metrics.originalQName : &question->qname;
isForCell = (question->qDNSServer && question->qDNSServer->cellIntf);
durationMs = ((m->timenow - question->metrics.firstQueryTime) * 1000) / mDNSPlatformOneSecond;
- MetricsUpdateUDNSQueryStats(queryName, question->qtype, mDNSNULL, question->metrics.querySendCount, durationMs, isForCell);
+ MetricsUpdateDNSQueryStats(queryName, question->qtype, mDNSNULL, question->metrics.querySendCount, durationMs, isForCell);
}
#endif
// Take care to cut question from list *before* calling UpdateQuestionDuplicates
diff --git a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
index 0e96058d..72ff7ca1 100755
--- a/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
+++ b/mDNSResponder/mDNSCore/mDNSEmbeddedAPI.h
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1896,7 +1896,7 @@ typedef enum { DNSSECValNotRequired = 0, DNSSECValRequired, DNSSECValInProgress,
// RFC 4122 defines it to be 16 bytes
#define UUID_SIZE 16
-#define AWD_METRICS (USE_AWD && TARGET_OS_EMBEDDED)
+#define AWD_METRICS (USE_AWD && TARGET_OS_IOS)
#if AWD_METRICS
typedef struct
@@ -2039,7 +2039,7 @@ struct DNSQuestion_struct
domainname *qnameOrig; // Copy of the original question name if it is not fully qualified
mDNSQuestionCallback *QuestionCallback;
void *QuestionContext;
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
uDNSMetrics metrics; // Data used for collecting unicast DNS query metrics.
#endif
#if USE_DNS64
diff --git a/mDNSResponder/mDNSCore/uDNS.c b/mDNSResponder/mDNSCore/uDNS.c
index dc87724c..4d011427 100755
--- a/mDNSResponder/mDNSCore/uDNS.c
+++ b/mDNSResponder/mDNSCore/uDNS.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4 -*-
*
- * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,10 @@
#endif
#include "uDNS.h"
+#if AWD_METRICS
+#include "Metrics.h"
+#endif
+
#if (defined(_MSC_VER))
// Disable "assignment within conditional expression".
// Other compilers understand the convention that if you place the assignment expression within an extra pair
@@ -1329,6 +1333,12 @@ mDNSlocal void tcpCallback(TCPSocket *sock, void *context, mDNSBool ConnectionEs
err = mDNSSendDNSMessage(m, &tcpInfo->request, end, mDNSInterface_Any, mDNSNULL, &tcpInfo->Addr, tcpInfo->Port, sock, AuthInfo, mDNSfalse);
if (err) { debugf("ERROR: tcpCallback: mDNSSendDNSMessage - %d", err); err = mStatus_UnknownErr; goto exit; }
+#if AWD_METRICS
+ if (mDNSSameIPPort(tcpInfo->Port, UnicastDNSPort))
+ {
+ MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&tcpInfo->request));
+ }
+#endif
// Record time we sent this question
if (q)
@@ -4758,9 +4768,10 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
else
{
err = mDNSSendDNSMessage(m, &m->omsg, end, q->qDNSServer->interface, q->LocalSocket, &q->qDNSServer->addr, q->qDNSServer->port, mDNSNULL, mDNSNULL, q->UseBackgroundTrafficClass);
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
if (!err)
{
+ MetricsUpdateDNSQuerySize((mDNSu32)(end - (mDNSu8 *)&m->omsg));
if (q->metrics.answered)
{
q->metrics.querySendCount = 0;
diff --git a/mDNSResponder/mDNSMacOSX/Metrics.h b/mDNSResponder/mDNSMacOSX/Metrics.h
index dbe6196a..ff419fd8 100644
--- a/mDNSResponder/mDNSMacOSX/Metrics.h
+++ b/mDNSResponder/mDNSMacOSX/Metrics.h
@@ -1,6 +1,5 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2016 Apple Inc. All rights reserved.
+/*
+ * Copyright (c) 2016-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,19 +14,22 @@
* limitations under the License.
*/
-#include "mDNSEmbeddedAPI.h"
-
#ifndef __Metrics_h
#define __Metrics_h
+#include "mDNSEmbeddedAPI.h"
+#include <TargetConditionals.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-#if TARGET_OS_EMBEDDED
+#if TARGET_OS_IOS
mStatus MetricsInit(void);
-void MetricsUpdateUDNSQueryStats(const domainname *inQueryName, mDNSu16 inType, const ResourceRecord *inRR, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCell);
-void MetricsUpdateUDNSResolveStats(const domainname *inQueryName, const ResourceRecord *inRR, mDNSBool inForCell);
+void MetricsUpdateDNSQueryStats(const domainname *inQueryName, mDNSu16 inType, const ResourceRecord *inRR, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCell);
+void MetricsUpdateDNSResolveStats(const domainname *inQueryName, const ResourceRecord *inRR, mDNSBool inForCell);
+void MetricsUpdateDNSQuerySize(mDNSu32 inSize);
+void MetricsUpdateDNSResponseSize(mDNSu32 inSize);
void LogMetrics(void);
#endif
diff --git a/mDNSResponder/mDNSMacOSX/Metrics.m b/mDNSResponder/mDNSMacOSX/Metrics.m
index f8a3ae73..e540f3be 100644
--- a/mDNSResponder/mDNSMacOSX/Metrics.m
+++ b/mDNSResponder/mDNSMacOSX/Metrics.m
@@ -1,6 +1,5 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2016 Apple Inc. All rights reserved.
+/*
+ * Copyright (c) 2016-2017 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,18 +16,19 @@
#import "Metrics.h"
-#if (TARGET_OS_EMBEDDED)
+#if (TARGET_OS_IOS)
#import <CoreUtils/SoftLinking.h>
#import <WirelessDiagnostics/AWDDNSDomainStats.h>
+#import <WirelessDiagnostics/AWDMDNSResponderDNSMessageSizeStats.h>
#import <WirelessDiagnostics/AWDMDNSResponderDNSStatistics.h>
#import <WirelessDiagnostics/AWDMDNSResponderResolveStats.h>
#import <WirelessDiagnostics/AWDMDNSResponderResolveStatsDNSServer.h>
#import <WirelessDiagnostics/AWDMDNSResponderResolveStatsDomain.h>
#import <WirelessDiagnostics/AWDMDNSResponderResolveStatsHostname.h>
#import <WirelessDiagnostics/AWDMDNSResponderResolveStatsResult.h>
+#import <WirelessDiagnostics/AWDMDNSResponderServicesStats.h>
#import <WirelessDiagnostics/AWDMetricIds_MDNSResponder.h>
#import <WirelessDiagnostics/WirelessDiagnostics.h>
-#import <WirelessDiagnostics/AWDMDNSResponderServicesStats.h>
#import "DNSCommon.h"
#import "mDNSMacOSX.h"
@@ -40,25 +40,45 @@
SOFT_LINK_FRAMEWORK(PrivateFrameworks, WirelessDiagnostics)
-SOFT_LINK_CLASS(WirelessDiagnostics, AWDDNSDomainStats)
+// AWDServerConnection class
+
+SOFT_LINK_CLASS(WirelessDiagnostics, AWDServerConnection)
+
+#define AWDServerConnectionSoft getAWDServerConnectionClass()
+
+// Classes for query stats
+
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderDNSStatistics)
+SOFT_LINK_CLASS(WirelessDiagnostics, AWDDNSDomainStats)
+
+#define AWDMDNSResponderDNSStatisticsSoft getAWDMDNSResponderDNSStatisticsClass()
+#define AWDDNSDomainStatsSoft getAWDDNSDomainStatsClass()
+
+// Classes for resolve stats
+
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderResolveStats)
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderResolveStatsDNSServer)
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderResolveStatsDomain)
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderResolveStatsHostname)
SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderResolveStatsResult)
-SOFT_LINK_CLASS(WirelessDiagnostics, AWDServerConnection)
-SOFT_LINK_CLASS(WirelessDiagnostics, AWDMetricManager)
-#define AWDDNSDomainStatsSoft getAWDDNSDomainStatsClass()
-#define AWDMDNSResponderDNSStatisticsSoft getAWDMDNSResponderDNSStatisticsClass()
#define AWDMDNSResponderResolveStatsSoft getAWDMDNSResponderResolveStatsClass()
-#define AWDMDNSResponderResolveStatsResultSoft getAWDMDNSResponderResolveStatsResultClass()
#define AWDMDNSResponderResolveStatsDNSServerSoft getAWDMDNSResponderResolveStatsDNSServerClass()
#define AWDMDNSResponderResolveStatsDomainSoft getAWDMDNSResponderResolveStatsDomainClass()
#define AWDMDNSResponderResolveStatsHostnameSoft getAWDMDNSResponderResolveStatsHostnameClass()
-#define AWDServerConnectionSoft getAWDServerConnectionClass()
-#define AWDMetricManagerSoft getAWDMetricManagerClass()
+#define AWDMDNSResponderResolveStatsResultSoft getAWDMDNSResponderResolveStatsResultClass()
+
+// Classes for services stats
+
+SOFT_LINK_CLASS(WirelessDiagnostics, AWDMetricManager)
+
+#define AWDMetricManagerSoft getAWDMetricManagerClass()
+
+// Classes for DNS message size stats
+
+SOFT_LINK_CLASS(WirelessDiagnostics, AWDMDNSResponderDNSMessageSizeStats)
+
+#define AWDMDNSResponderDNSMessageSizeStatsSoft getAWDMDNSResponderDNSMessageSizeStatsClass()
//===========================================================================================================================
// Macros
@@ -82,31 +102,26 @@ SOFT_LINK_CLASS(WirelessDiagnostics, AWDMetricManager)
// Data structures
//===========================================================================================================================
-typedef struct
-{
- const char * cstr; // Name of domain as a c-string.
- const domainname * name; // Name of domain as length-prefixed labels.
- int labelCount; // Number of labels in domain name. Used for domain name comparisons.
+// Data structures for query stats.
-} Domain;
+typedef struct QueryStats QueryStats;
+typedef struct DNSHistSet DNSHistSet;
+typedef mDNSBool (*QueryNameTest_f)(const QueryStats *inStats, const domainname *inQueryName);
-// Important: Do not add to this list without getting privacy approval beforehand. See <rdar://problem/24155761&26397203>.
-// If you get approval and do add a domain to this list, make sure it passes ValidateDNSStatsDomains() below.
-
-static const Domain kQueryStatsDomains[] =
+struct QueryStats
{
- { ".", (domainname *)"", 0 },
- { "apple.com.", (domainname *)"\x5" "apple" "\x3" "com", 2 },
- { "icloud.com.", (domainname *)"\x6" "icloud" "\x3" "com", 2 },
- { "mzstatic.com.", (domainname *)"\x8" "mzstatic" "\x3" "com", 2 },
- { "google.com.", (domainname *)"\x6" "google" "\x3" "com", 2 },
- { "facebook.com.", (domainname *)"\x8" "facebook" "\x3" "com", 2 },
- { "baidu.com.", (domainname *)"\x5" "baidu" "\x3" "com", 2 },
- { "yahoo.com.", (domainname *)"\x5" "yahoo" "\x3" "com", 2 },
- { "qq.com.", (domainname *)"\x2" "qq" "\x3" "com", 2 },
+ QueryStats * next; // Pointer to next domain stats in list.
+ const char * domainStr; // Domain (see below) as a C string.
+ uint8_t * domain; // Domain for which these stats are collected.
+ const char * altDomainStr; // Alt domain string to use in the AWD version of the stats instead of domainStr.
+ DNSHistSet * nonCellular; // Query stats for queries sent over non-cellular interfaces.
+ DNSHistSet * cellular; // Query stats for queries sent over cellular interfaces.
+ QueryNameTest_f test; // Function that tests whether a given query's stats belong based on the query name.
+ int labelCount; // Number of labels in domain name. Used for domain name comparisons.
+ mDNSBool terminal; // If true and test passes, then no other QueryStats on the list should be visited.
};
-check_compile_time(countof(kQueryStatsDomains) == 9);
+check_compile_time(sizeof(QueryStats) <= 64);
// DNSHist contains the per domain per network type histogram data that goes in a DNSDomainStats protobuf message. See
// <rdar://problem/23980546> MDNSResponder.proto update.
@@ -164,30 +179,29 @@ check_compile_time(countof_field(DNSHist, unansweredQueryDurationBins) == (count
check_compile_time(countof_field(DNSHist, responseLatencyBins) == (countof(kResponseLatencyMsLimits) + 1));
check_compile_time(countof_field(DNSHist, negResponseLatencyBins) == (countof(kResponseLatencyMsLimits) + 1));
-typedef struct
+struct DNSHistSet
{
DNSHist * histA; // Histogram data for queries for A resource records.
DNSHist * histAAAA; // Histogram data for queries for AAAA resource records.
+};
-} DNSHistSet;
-
-typedef struct DNSDomainStats DNSDomainStats;
-struct DNSDomainStats
+typedef struct
{
- DNSDomainStats * next; // Pointer to next domain stats in list.
- const Domain * domain; // Domain for which these stats are collected.
- DNSHistSet * nonCellular; // Query stats for queries sent over non-cellular interfaces.
- DNSHistSet * cellular; // Query stats for queries sent over cellular interfaces.
-};
+ const char * domainStr;
+ const char * altDomainStr;
+ QueryNameTest_f test;
+ mDNSBool terminal;
+
+} QueryStatsArgs;
-check_compile_time(sizeof(struct DNSDomainStats) <= 32);
+// Data structures for resolve stats.
-static const Domain kResolveStatsDomains[] =
+static const char * const kResolveStatsDomains[] =
{
- { "apple.com.", (domainname *)"\x5" "apple" "\x3" "com", 2 },
- { "icloud.com.", (domainname *)"\x6" "icloud" "\x3" "com", 2 },
- { "mzstatic.com.", (domainname *)"\x8" "mzstatic" "\x3" "com", 2 },
- { "me.com.", (domainname *)"\x2" "me" "\x3" "com", 2 },
+ "apple.com.",
+ "icloud.com.",
+ "mzstatic.com.",
+ "me.com."
};
check_compile_time(countof(kResolveStatsDomains) == 4);
@@ -202,10 +216,14 @@ typedef struct ResolveStatsNegAAAASet ResolveStatsNegAAAASet;
struct ResolveStatsDomain
{
ResolveStatsDomain * next; // Next domain object in list.
+ const char * domainStr;
+ uint8_t * domain; // Domain for which these stats are collected.
+ int labelCount; // Number of labels in domain name. Used for domain name comparisons.
ResolveStatsHostname * hostnameList; // List of hostname objects in this domain.
- const Domain * domainInfo; // Pointer to domain info.
};
+check_compile_time(sizeof(ResolveStatsDomain) <= 40);
+
struct ResolveStatsHostname
{
ResolveStatsHostname * next; // Next hostname object in list.
@@ -290,27 +308,52 @@ typedef struct
} Response;
-//===========================================================================================================================
-// Globals
-//===========================================================================================================================
+// Data structures for DNS message size stats.
-static DNSDomainStats * gDomainStatsList = NULL;
-static ResolveStatsDomain * gResolveStatsList = NULL;
-static ResolveStatsDNSServer * gResolveStatsServerList = NULL;
-static unsigned int gResolveStatsNextServerID = 0;
-static int gResolveStatsObjCount = 0;
-static AWDServerConnection * gAWDServerConnection = nil;
+#define kQuerySizeBinWidth 16
+#define kQuerySizeBinMax 512
+#define kQuerySizeBinCount ((kQuerySizeBinMax / kQuerySizeBinWidth) + 1)
+
+check_compile_time(kQuerySizeBinWidth > 0);
+check_compile_time(kQuerySizeBinCount > 0);
+check_compile_time((kQuerySizeBinMax % kQuerySizeBinWidth) == 0);
+
+#define kResponseSizeBinWidth 16
+#define kResponseSizeBinMax 512
+#define kResponseSizeBinCount ((kResponseSizeBinMax / kResponseSizeBinWidth) + 1)
+
+check_compile_time(kResponseSizeBinWidth > 0);
+check_compile_time(kResponseSizeBinCount > 0);
+check_compile_time((kResponseSizeBinMax % kResponseSizeBinWidth) == 0);
+
+typedef struct
+{
+ uint16_t querySizeBins[kQuerySizeBinCount];
+ uint16_t responseSizeBins[kResponseSizeBinCount];
+
+} DNSMessageSizeStats;
+
+check_compile_time(sizeof(DNSMessageSizeStats) <= 132);
//===========================================================================================================================
// Local Prototypes
//===========================================================================================================================
-mDNSlocal mStatus DNSDomainStatsCreate(const Domain *inDomain, DNSDomainStats **outStats);
-mDNSlocal void DNSDomainStatsFree(DNSDomainStats *inStats);
-mDNSlocal void DNSDomainStatsFreeList(DNSDomainStats *inList);
-mDNSlocal mStatus DNSDomainStatsUpdate(DNSDomainStats *inStats, int inType, const ResourceRecord *inRR, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs, mDNSBool inForCell);
+// Query stats
+
+mDNSlocal mStatus QueryStatsCreate(const char *inDomainStr, const char *inAltDomainStr, QueryNameTest_f inTest, mDNSBool inTerminal, QueryStats **outStats);
+mDNSlocal void QueryStatsFree(QueryStats *inStats);
+mDNSlocal void QueryStatsFreeList(QueryStats *inList);
+mDNSlocal mStatus QueryStatsUpdate(QueryStats *inStats, int inType, const ResourceRecord *inRR, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs, mDNSBool inForCell);
+mDNSlocal const char * QueryStatsGetDomainString(const QueryStats *inStats);
+mDNSlocal mDNSBool QueryStatsDomainTest(const QueryStats *inStats, const domainname *inQueryName);
+mDNSlocal mDNSBool QueryStatsHostnameTest(const QueryStats *inStats, const domainname *inQueryName);
+mDNSlocal mDNSBool QueryStatsContentiCloudTest(const QueryStats *inStats, const domainname *inQueryName);
+mDNSlocal mDNSBool QueryStatsCourierPushTest(const QueryStats *inStats, const domainname *inQueryName);
-mDNSlocal mStatus ResolveStatsDomainCreate(const Domain *inDomain, ResolveStatsDomain **outDomain);
+// Resolve stats
+
+mDNSlocal mStatus ResolveStatsDomainCreate(const char *inDomainStr, ResolveStatsDomain **outDomain);
mDNSlocal void ResolveStatsDomainFree(ResolveStatsDomain *inDomain);
mDNSlocal mStatus ResolveStatsDomainUpdate(ResolveStatsDomain *inDomain, const domainname *inHostname, const Response *inResp, const mDNSAddr *inDNSAddr, mDNSBool inForCell);
mDNSlocal mStatus ResolveStatsDomainCreateAWDVersion(const ResolveStatsDomain *inDomain, AWDMDNSResponderResolveStatsDomain **outDomain);
@@ -334,22 +377,58 @@ mDNSlocal mStatus ResolveStatsNegAAAASetCreate(ResolveStatsNegAAAASet **outSet
mDNSlocal void ResolveStatsNegAAAASetFree(ResolveStatsNegAAAASet *inSet);
mDNSlocal mStatus ResolveStatsGetServerID(const mDNSAddr *inServerAddr, mDNSBool inForCell, uint8_t *outServerID);
-mDNSlocal mStatus CreateDomainStatsList(DNSDomainStats **outList);
+// DNS message size stats
+
+mDNSlocal mStatus DNSMessageSizeStatsCreate(DNSMessageSizeStats **outStats);
+mDNSlocal void DNSMessageSizeStatsFree(DNSMessageSizeStats *inStats);
+
+mDNSlocal mStatus CreateQueryStatsList(QueryStats **outList);
mDNSlocal mStatus CreateResolveStatsList(ResolveStatsDomain **outList);
mDNSlocal void FreeResolveStatsList(ResolveStatsDomain *inList);
mDNSlocal void FreeResolveStatsServerList(ResolveStatsDNSServer *inList);
mDNSlocal mStatus SubmitAWDMetric(UInt32 inMetricID);
mDNSlocal mStatus SubmitAWDMetricQueryStats(void);
mDNSlocal mStatus SubmitAWDMetricResolveStats(void);
+mDNSlocal mStatus SubmitAWDMetricDNSMessageSizeStats(void);
mDNSlocal mStatus CreateAWDDNSDomainStats(DNSHist *inHist, const char *inDomain, mDNSBool inForCell, AWDDNSDomainStats_RecordType inType, AWDDNSDomainStats **outStats);
-mDNSlocal mStatus AddAWDDNSDomainStats(AWDMDNSResponderDNSStatistics *inMetric, DNSHistSet *inSet, const char *inDomain, mDNSBool inForCell);
mDNSlocal void LogDNSHistSet(const DNSHistSet *inSet, const char *inDomain, mDNSBool inForCell);
mDNSlocal void LogDNSHist(const DNSHist *inHist, const char *inDomain, mDNSBool inForCell, const char *inType);
mDNSlocal void LogDNSHistSendCounts(const uint16_t inSendCountBins[kQueryStatsSendCountBinCount]);
mDNSlocal void LogDNSHistLatencies(const uint16_t inLatencyBins[kQueryStatsLatencyBinCount]);
-#if (METRICS_VALIDATE_DNS_STATS_DOMAINS)
-mDNSlocal void ValidateDNSStatsDomains(void);
-#endif
+mDNSlocal void LogDNSMessageSizeStats(const uint16_t *inBins, size_t inBinCount, unsigned int inBinWidth);
+
+mDNSlocal size_t CopyHistogramBins(uint32_t *inDstBins, uint16_t *inSrcBins, size_t inBinCount);
+
+//===========================================================================================================================
+// Globals
+//===========================================================================================================================
+
+static AWDServerConnection * gAWDServerConnection = nil;
+static QueryStats * gQueryStatsList = NULL;
+static ResolveStatsDomain * gResolveStatsList = NULL;
+static ResolveStatsDNSServer * gResolveStatsServerList = NULL;
+static unsigned int gResolveStatsNextServerID = 0;
+static int gResolveStatsObjCount = 0;
+static DNSMessageSizeStats * gDNSMessageSizeStats = NULL;
+
+// Important: Do not add to this list without getting privacy approval. See <rdar://problem/24155761&26397203&34763471>.
+
+static const QueryStatsArgs kQueryStatsArgs[] =
+{
+ { ".", NULL, QueryStatsDomainTest, mDNSfalse },
+ { "", "alt:*-courier.push.apple.com.", QueryStatsCourierPushTest, mDNSfalse },
+ { "apple.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "gateway.icloud.com.", "alt:gateway.icloud.com", QueryStatsHostnameTest, mDNSfalse },
+ { "", "alt:*-content.icloud.com.", QueryStatsContentiCloudTest, mDNSfalse },
+ { "icloud.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "mzstatic.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "google.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "baidu.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "yahoo.com.", NULL, QueryStatsDomainTest, mDNStrue },
+ { "qq.com.", NULL, QueryStatsDomainTest, mDNStrue }
+};
+
+check_compile_time(countof(kQueryStatsArgs) == 11);
//===========================================================================================================================
// MetricsInit
@@ -357,10 +436,6 @@ mDNSlocal void ValidateDNSStatsDomains(void);
mStatus MetricsInit(void)
{
-#if (METRICS_VALIDATE_DNS_STATS_DOMAINS)
- ValidateDNSStatsDomains();
-#endif
-
@autoreleasepool
{
gAWDServerConnection = [[AWDServerConnectionSoft alloc]
@@ -389,6 +464,13 @@ mStatus MetricsInit(void)
SubmitAWDMetric(inMetricID);
}
forIdentifier: (UInt32)AWDMetricId_MDNSResponder_ServicesStats];
+
+ [gAWDServerConnection
+ registerQueriableMetricCallback: ^(UInt32 inMetricID)
+ {
+ SubmitAWDMetric(inMetricID);
+ }
+ forIdentifier: (UInt32)AWDMetricId_MDNSResponder_DNSMessageSizeStats];
}
else
{
@@ -398,56 +480,33 @@ mStatus MetricsInit(void)
if( gAWDServerConnection )
{
- CreateDomainStatsList(&gDomainStatsList);
+ CreateQueryStatsList(&gQueryStatsList);
CreateResolveStatsList(&gResolveStatsList);
+ DNSMessageSizeStatsCreate(&gDNSMessageSizeStats);
}
return (mStatus_NoError);
}
//===========================================================================================================================
-// MetricsUpdateUDNSQueryStats
+// MetricsUpdateDNSQueryStats
//===========================================================================================================================
-mDNSexport void MetricsUpdateUDNSQueryStats(const domainname *inQueryName, mDNSu16 inType, const ResourceRecord *inRR, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCell)
+mDNSexport void MetricsUpdateDNSQueryStats(const domainname *inQueryName, mDNSu16 inType, const ResourceRecord *inRR, mDNSu32 inSendCount, mDNSu32 inLatencyMs, mDNSBool inForCell)
{
- DNSDomainStats * stats;
- int queryLabelCount;
- const domainname * queryParentDomain;
- mDNSBool isQueryInDomain;
- int skipCount;
- int skipCountLast = -1;
+ QueryStats * stats;
+ mDNSBool match;
require_quiet(gAWDServerConnection, exit);
require_quiet((inType == kDNSType_A) || (inType == kDNSType_AAAA), exit);
- queryLabelCount = CountLabels(inQueryName);
-
- for (stats = gDomainStatsList; stats; stats = stats->next)
+ for (stats = gQueryStatsList; stats; stats = stats->next)
{
- isQueryInDomain = mDNSfalse;
- if (strcmp(stats->domain->cstr, ".") == 0)
- {
- // All queries are in the root domain.
- isQueryInDomain = mDNStrue;
- }
- else
- {
- skipCount = queryLabelCount - stats->domain->labelCount;
- if (skipCount >= 0)
- {
- if (skipCount != skipCountLast)
- {
- queryParentDomain = SkipLeadingLabels(inQueryName, skipCount);
- skipCountLast = skipCount;
- }
- isQueryInDomain = SameDomainName(queryParentDomain, stats->domain->name);
- }
- }
-
- if (isQueryInDomain)
+ match = stats->test(stats, inQueryName);
+ if (match)
{
- DNSDomainStatsUpdate(stats, inType, inRR, inSendCount, inLatencyMs, inForCell);
+ QueryStatsUpdate(stats, inType, inRR, inSendCount, inLatencyMs, inForCell);
+ if (stats->terminal) break;
}
}
@@ -456,12 +515,12 @@ exit:
}
//===========================================================================================================================
-// MetricsUpdateUDNSResolveStats
+// MetricsUpdateDNSResolveStats
//===========================================================================================================================
-mDNSexport void MetricsUpdateUDNSResolveStats(const domainname *inQueryName, const ResourceRecord *inRR, mDNSBool inForCell)
+mDNSexport void MetricsUpdateDNSResolveStats(const domainname *inQueryName, const ResourceRecord *inRR, mDNSBool inForCell)
{
- ResolveStatsDomain * domain;
+ ResolveStatsDomain * domainStats;
domainname hostname;
size_t hostnameLen;
mDNSBool isQueryInDomain;
@@ -477,10 +536,10 @@ mDNSexport void MetricsUpdateUDNSResolveStats(const domainname *inQueryName, con
queryLabelCount = CountLabels(inQueryName);
- for (domain = gResolveStatsList; domain; domain = domain->next)
+ for (domainStats = gResolveStatsList; domainStats; domainStats = domainStats->next)
{
isQueryInDomain = mDNSfalse;
- skipCount = queryLabelCount - domain->domainInfo->labelCount;
+ skipCount = queryLabelCount - domainStats->labelCount;
if (skipCount >= 0)
{
if (skipCount != skipCountLast)
@@ -488,7 +547,7 @@ mDNSexport void MetricsUpdateUDNSResolveStats(const domainname *inQueryName, con
queryParentDomain = SkipLeadingLabels(inQueryName, skipCount);
skipCountLast = skipCount;
}
- isQueryInDomain = SameDomainName(queryParentDomain, domain->domainInfo->name);
+ isQueryInDomain = SameDomainName(queryParentDomain, (const domainname *)domainStats->domain);
}
if (!isQueryInDomain) continue;
@@ -508,7 +567,7 @@ mDNSexport void MetricsUpdateUDNSResolveStats(const domainname *inQueryName, con
response.type = (inRR->rrtype == kDNSType_A) ? kResponseType_IPv4Addr : kResponseType_IPv6Addr;
response.data = (inRR->rrtype == kDNSType_A) ? inRR->rdata->u.ipv4.b : inRR->rdata->u.ipv6.b;
}
- ResolveStatsDomainUpdate(domain, &hostname, &response, &inRR->rDNSServer->addr, inForCell);
+ ResolveStatsDomainUpdate(domainStats, &hostname, &response, &inRR->rDNSServer->addr, inForCell);
}
exit:
@@ -516,12 +575,44 @@ exit:
}
//===========================================================================================================================
+// MetricsUpdateDNSQuerySize
+//===========================================================================================================================
+
+mDNSlocal void UpdateMessageSizeCounts(uint16_t *inBins, size_t inBinCount, unsigned int inBinWidth, uint32_t inSize);
+
+mDNSexport void MetricsUpdateDNSQuerySize(mDNSu32 inSize)
+{
+ if (!gDNSMessageSizeStats) return;
+ UpdateMessageSizeCounts(gDNSMessageSizeStats->querySizeBins, kQuerySizeBinCount, kQuerySizeBinWidth, inSize);
+}
+
+mDNSlocal void UpdateMessageSizeCounts(uint16_t *inBins, size_t inBinCount, unsigned int inBinWidth, uint32_t inSize)
+{
+ size_t i;
+
+ if (inSize == 0) return;
+ i = (inSize - 1) / inBinWidth;
+ if (i >= inBinCount) i = inBinCount - 1;
+ increment_saturate(inBins[i], UINT16_MAX);
+}
+
+//===========================================================================================================================
+// MetricsUpdateDNSResponseSize
+//===========================================================================================================================
+
+mDNSexport void MetricsUpdateDNSResponseSize(mDNSu32 inSize)
+{
+ if (!gDNSMessageSizeStats) return;
+ UpdateMessageSizeCounts(gDNSMessageSizeStats->responseSizeBins, kResponseSizeBinCount, kResponseSizeBinWidth, inSize);
+}
+
+//===========================================================================================================================
// LogMetrics
//===========================================================================================================================
mDNSexport void LogMetrics(void)
{
- DNSDomainStats * stats;
+ QueryStats * stats;
const ResolveStatsDomain * domain;
const ResolveStatsHostname * hostname;
const ResolveStatsDNSServer * server;
@@ -538,15 +629,15 @@ mDNSexport void LogMetrics(void)
LogMsgNoIdent("gAWDServerConnection %p", gAWDServerConnection);
LogMsgNoIdent("---- DNS query stats by domain -----");
- for (stats = gDomainStatsList; stats; stats = stats->next)
+ for (stats = gQueryStatsList; stats; stats = stats->next)
{
if (!stats->nonCellular && !stats->cellular)
{
- LogMsgNoIdent("No data for %s", stats->domain->cstr);
+ LogMsgNoIdent("No data for %s", QueryStatsGetDomainString(stats));
continue;
}
- if (stats->nonCellular) LogDNSHistSet(stats->nonCellular, stats->domain->cstr, mDNSfalse);
- if (stats->cellular) LogDNSHistSet(stats->cellular, stats->domain->cstr, mDNStrue);
+ if (stats->nonCellular) LogDNSHistSet(stats->nonCellular, QueryStatsGetDomainString(stats), mDNSfalse);
+ if (stats->cellular) LogDNSHistSet(stats->cellular, QueryStatsGetDomainString(stats), mDNStrue);
}
LogMsgNoIdent("---- DNS resolve stats by domain -----");
@@ -565,7 +656,7 @@ mDNSexport void LogMetrics(void)
for (hostname = domain->hostnameList; hostname; hostname = hostname->next) { hostnameCount++; }
hostnameObjCount += hostnameCount;
- LogMsgNoIdent("%##s (%d hostname%s)", domain->domainInfo->name, hostnameCount, (hostnameCount == 1) ? "" : "s");
+ LogMsgNoIdent("%s (%d hostname%s)", domain->domainStr, hostnameCount, (hostnameCount == 1) ? "" : "s");
for (hostname = domain->hostnameList; hostname; hostname = hostname->next)
{
@@ -622,39 +713,96 @@ mDNSexport void LogMetrics(void)
}
LogMsgNoIdent("Total object count: %3d (server %d hostname %d address %d)",
serverObjCount + hostnameObjCount + addrObjCount, serverObjCount, hostnameObjCount, addrObjCount);
-
+
LogMsgNoIdent("---- Num of Services Registered -----");
LogMsgNoIdent("Current_number_of_services_registered :[%d], Max_number_of_services_registered :[%d]",
curr_num_regservices, max_num_regservices);
+
+ if (gDNSMessageSizeStats)
+ {
+ LogMsgNoIdent("---- DNS query size stats ---");
+ LogDNSMessageSizeStats(gDNSMessageSizeStats->querySizeBins, kQuerySizeBinCount, kQuerySizeBinWidth);
+
+ LogMsgNoIdent("-- DNS response size stats --");
+ LogDNSMessageSizeStats(gDNSMessageSizeStats->responseSizeBins, kResponseSizeBinCount, kResponseSizeBinWidth);
+ }
+ else
+ {
+ LogMsgNoIdent("No DNS message size stats.");
+ }
}
//===========================================================================================================================
-// DNSDomainStatsCreate
+// QueryStatsCreate
//===========================================================================================================================
-mDNSlocal mStatus DNSDomainStatsCreate(const Domain *inDomain, DNSDomainStats **outStats)
+mDNSlocal mStatus StringToDomainName(const char *inString, uint8_t **outDomainName);
+
+mDNSlocal mStatus QueryStatsCreate(const char *inDomainStr, const char *inAltDomainStr, QueryNameTest_f inTest, mDNSBool inTerminal, QueryStats **outStats)
{
- mStatus err;
- DNSDomainStats * obj;
+ mStatus err;
+ QueryStats * obj;
- obj = (DNSDomainStats *)calloc(1, sizeof(*obj));
+ obj = (QueryStats *)calloc(1, sizeof(*obj));
require_action_quiet(obj, exit, err = mStatus_NoMemoryErr);
- obj->domain = inDomain;
+ obj->domainStr = inDomainStr;
+ err = StringToDomainName(obj->domainStr, &obj->domain);
+ require_noerr_quiet(err, exit);
+
+ obj->altDomainStr = inAltDomainStr;
+ obj->test = inTest;
+ obj->labelCount = CountLabels((const domainname *)obj->domain);
+ obj->terminal = inTerminal;
*outStats = obj;
+ obj = NULL;
err = mStatus_NoError;
exit:
+ if (obj) QueryStatsFree(obj);
return (err);
}
+mDNSlocal mStatus StringToDomainName(const char *inString, uint8_t **outDomainName)
+{
+ mStatus err;
+ uint8_t * domainPtr = NULL;
+ size_t domainLen;
+ const mDNSu8 * ptr;
+ domainname domain;
+
+ if (strcmp(inString, ".") == 0)
+ {
+ domain.c[0] = 0;
+ }
+ else
+ {
+ ptr = MakeDomainNameFromDNSNameString(&domain, inString);
+ require_action_quiet(ptr, exit, err = mStatus_BadParamErr);
+ }
+ domainLen = DomainNameLength(&domain);
+
+ domainPtr = (uint8_t *)malloc(domainLen);
+ require_action_quiet(domainPtr, exit, err = mStatus_NoMemoryErr);
+
+ memcpy(domainPtr, domain.c, domainLen);
+
+ *outDomainName = domainPtr;
+ domainPtr = NULL;
+ err = mStatus_NoError;
+
+exit:
+ return(err);
+}
+
//===========================================================================================================================
-// DNSDomainStatsFree
+// QueryStatsFree
//===========================================================================================================================
-mDNSlocal void DNSDomainStatsFree(DNSDomainStats *inStats)
+mDNSlocal void QueryStatsFree(QueryStats *inStats)
{
+ ForgetMem(&inStats->domain);
if (inStats->nonCellular)
{
ForgetMem(&inStats->nonCellular->histA);
@@ -673,25 +821,25 @@ mDNSlocal void DNSDomainStatsFree(DNSDomainStats *inStats)
}
//===========================================================================================================================
-// DNSDomainStatsFreeList
+// QueryStatsFreeList
//===========================================================================================================================
-mDNSlocal void DNSDomainStatsFreeList(DNSDomainStats *inList)
+mDNSlocal void QueryStatsFreeList(QueryStats *inList)
{
- DNSDomainStats * stats;
+ QueryStats * stats;
while ((stats = inList) != NULL)
{
inList = stats->next;
- DNSDomainStatsFree(stats);
+ QueryStatsFree(stats);
}
}
//===========================================================================================================================
-// DNSDomainStatsUpdate
+// QueryStatsUpdate
//===========================================================================================================================
-mDNSlocal mStatus DNSDomainStatsUpdate(DNSDomainStats *inStats, int inType, const ResourceRecord *inRR, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs, mDNSBool inForCell)
+mDNSlocal mStatus QueryStatsUpdate(QueryStats *inStats, int inType, const ResourceRecord *inRR, mDNSu32 inQuerySendCount, mDNSu32 inLatencyMs, mDNSBool inForCell)
{
mStatus err;
DNSHistSet * set;
@@ -751,10 +899,141 @@ exit:
}
//===========================================================================================================================
+// QueryStatsGetDomainString
+//===========================================================================================================================
+
+mDNSlocal const char * QueryStatsGetDomainString(const QueryStats *inStats)
+{
+ return (inStats->altDomainStr ? inStats->altDomainStr : inStats->domainStr);
+}
+
+//===========================================================================================================================
+// QueryStatsDomainTest
+//===========================================================================================================================
+
+mDNSlocal mDNSBool QueryStatsDomainTest(const QueryStats *inStats, const domainname *inQueryName)
+{
+ const domainname * parentDomain;
+ int labelCount;
+
+ if (inStats->domain[0] == 0) return (mDNStrue);
+
+ labelCount = CountLabels(inQueryName);
+ if (labelCount < inStats->labelCount) return (mDNSfalse);
+
+ parentDomain = SkipLeadingLabels(inQueryName, labelCount - inStats->labelCount);
+ return (SameDomainName(parentDomain, (const domainname *)inStats->domain));
+}
+
+//===========================================================================================================================
+// QueryStatsHostnameTest
+//===========================================================================================================================
+
+mDNSlocal mDNSBool QueryStatsHostnameTest(const QueryStats *inStats, const domainname *inQueryName)
+{
+ return (SameDomainName(inQueryName, (const domainname *)inStats->domain));
+}
+
+//===========================================================================================================================
+// QueryStatsContentiCloudTest
+//===========================================================================================================================
+
+mDNSlocal const uint8_t *LocateLabelSuffix(const uint8_t *inLabel, const uint8_t *inSuffixPtr, size_t inSuffixLen);
+
+#define kContentSuffixStr "-content"
+
+mDNSlocal mDNSBool QueryStatsContentiCloudTest(const QueryStats *inStats, const domainname *inQueryName)
+{
+ const mDNSu8 * const firstLabel = inQueryName->c;
+ const uint8_t * suffix;
+ const domainname * parentDomain;
+ int labelCount;
+
+ (void) inStats; // Unused.
+
+ labelCount = CountLabels(inQueryName);
+ if (labelCount != 3) return (mDNSfalse);
+
+ suffix = LocateLabelSuffix(firstLabel, (const uint8_t *)kContentSuffixStr, sizeof_string(kContentSuffixStr));
+ if (suffix && (suffix > &firstLabel[1]))
+ {
+ parentDomain = SkipLeadingLabels(inQueryName, 1);
+ if (SameDomainName(parentDomain, (const domainname *)"\x6" "icloud" "\x3" "com"))
+ {
+ return (mDNStrue);
+ }
+ }
+
+ return (mDNSfalse);
+}
+
+mDNSlocal const uint8_t *LocateLabelSuffix(const uint8_t *inLabel, const uint8_t *inSuffixPtr, size_t inSuffixLen)
+{
+ const uint8_t * ptr;
+ const uint8_t * lp;
+ const uint8_t * sp;
+ size_t len;
+ const size_t labelLen = inLabel[0];
+
+ if (labelLen < inSuffixLen) return (NULL);
+
+ ptr = &inLabel[1 + labelLen - inSuffixLen];
+ lp = ptr;
+ sp = inSuffixPtr;
+ for (len = inSuffixLen; len > 0; --len)
+ {
+ if (tolower(*lp) != tolower(*sp)) return (NULL);
+ ++lp;
+ ++sp;
+ }
+
+ return (ptr);
+}
+
+//===========================================================================================================================
+// QueryStatsCourierPushTest
+//===========================================================================================================================
+
+#define kCourierSuffixStr "-courier"
+
+mDNSlocal mDNSBool QueryStatsCourierPushTest(const QueryStats *inStats, const domainname *inQueryName)
+{
+ const mDNSu8 * const firstLabel = inQueryName->c;
+ const uint8_t * suffix;
+ const uint8_t * ptr;
+ const domainname * parentDomain;
+ int labelCount;
+
+ (void) inStats; // Unused.
+
+ labelCount = CountLabels(inQueryName);
+ if (labelCount != 4) return (mDNSfalse);
+
+ suffix = LocateLabelSuffix(firstLabel, (const mDNSu8 *)kCourierSuffixStr, sizeof_string(kCourierSuffixStr));
+ if (suffix && (suffix > &firstLabel[1]))
+ {
+ for (ptr = &firstLabel[1]; ptr < suffix; ++ptr)
+ {
+ if (!isdigit(*ptr)) break;
+ }
+ if (ptr == suffix)
+ {
+ parentDomain = SkipLeadingLabels(inQueryName, 1);
+ if (SameDomainName(parentDomain, (const domainname *)"\x4" "push" "\x5" "apple" "\x3" "com"))
+ {
+ return (mDNStrue);
+ }
+ }
+ }
+
+ return (mDNSfalse);
+}
+
+//===========================================================================================================================
// ResolveStatsDomainCreate
//===========================================================================================================================
-mDNSlocal mStatus ResolveStatsDomainCreate(const Domain *inDomain, ResolveStatsDomain **outDomain)
+mDNSlocal mStatus ResolveStatsDomainCreate(const char *inDomainStr, ResolveStatsDomain **outDomain)
{
mStatus err;
ResolveStatsDomain * obj;
@@ -762,12 +1041,18 @@ mDNSlocal mStatus ResolveStatsDomainCreate(const Domain *inDomain, ResolveStatsD
obj = (ResolveStatsDomain *)calloc(1, sizeof(*obj));
require_action_quiet(obj, exit, err = mStatus_NoMemoryErr);
- obj->domainInfo = inDomain;
+ obj->domainStr = inDomainStr;
+ err = StringToDomainName(obj->domainStr, &obj->domain);
+ require_noerr_quiet(err, exit);
+
+ obj->labelCount = CountLabels((const domainname *)obj->domain);
*outDomain = obj;
+ obj = NULL;
err = mStatus_NoError;
exit:
+ if (obj) ResolveStatsDomainFree(obj);
return (err);
}
@@ -779,6 +1064,7 @@ mDNSlocal void ResolveStatsDomainFree(ResolveStatsDomain *inDomain)
{
ResolveStatsHostname * hostname;
+ ForgetMem(&inDomain->domain);
while ((hostname = inDomain->hostnameList) != NULL)
{
inDomain->hostnameList = hostname->next;
@@ -862,7 +1148,7 @@ mDNSlocal mStatus ResolveStatsDomainCreateAWDVersion(const ResolveStatsDomain *i
domain = [[AWDMDNSResponderResolveStatsDomainSoft alloc] init];
require_action_quiet(domain, exit, err = mStatus_UnknownErr);
- name = [[NSString alloc] initWithUTF8String:inDomain->domainInfo->cstr];
+ name = [[NSString alloc] initWithUTF8String:inDomain->domainStr];
require_action_quiet(name, exit, err = mStatus_UnknownErr);
domain.name = name;
@@ -1357,7 +1643,7 @@ mDNSlocal mStatus ResolveStatsGetServerID(const mDNSAddr *inServerAddr, mDNSBool
require_noerr_quiet(err, exit);
gResolveStatsObjCount++;
- server->id = gResolveStatsNextServerID++;
+ server->id = (uint8_t)gResolveStatsNextServerID++;
server->next = gResolveStatsServerList;
gResolveStatsServerList = server;
}
@@ -1376,21 +1662,50 @@ exit:
}
//===========================================================================================================================
-// CreateDomainStatsList
+// DNSMessageSizeStatsCreate
//===========================================================================================================================
-mDNSlocal mStatus CreateDomainStatsList(DNSDomainStats **outList)
+mDNSlocal mStatus DNSMessageSizeStatsCreate(DNSMessageSizeStats **outStats)
{
- mStatus err;
- int i;
- DNSDomainStats * stats;
- DNSDomainStats ** p;
- DNSDomainStats * list = NULL;
+ mStatus err;
+ DNSMessageSizeStats * stats;
+
+ stats = (DNSMessageSizeStats *)calloc(1, sizeof(*stats));
+ require_action_quiet(stats, exit, err = mStatus_NoMemoryErr);
+
+ *outStats = stats;
+ err = mStatus_NoError;
+
+exit:
+ return (err);
+}
+
+//===========================================================================================================================
+// DNSMessageSizeStatsFree
+//===========================================================================================================================
+
+mDNSlocal void DNSMessageSizeStatsFree(DNSMessageSizeStats *inStats)
+{
+ free(inStats);
+}
+
+//===========================================================================================================================
+// CreateQueryStatsList
+//===========================================================================================================================
+
+mDNSlocal mStatus CreateQueryStatsList(QueryStats **outList)
+{
+ mStatus err;
+ QueryStats ** p;
+ QueryStats * stats;
+ const QueryStatsArgs * args;
+ const QueryStatsArgs * const end = kQueryStatsArgs + countof(kQueryStatsArgs);
+ QueryStats * list = NULL;
p = &list;
- for (i = 0; i < (int)countof(kQueryStatsDomains); ++i)
+ for (args = kQueryStatsArgs; args < end; ++args)
{
- err = DNSDomainStatsCreate(&kQueryStatsDomains[i], &stats);
+ err = QueryStatsCreate(args->domainStr, args->altDomainStr, args->test, args->terminal, &stats);
require_noerr_quiet(err, exit);
*p = stats;
@@ -1399,9 +1714,10 @@ mDNSlocal mStatus CreateDomainStatsList(DNSDomainStats **outList)
*outList = list;
list = NULL;
+ err = mStatus_NoError;
exit:
- DNSDomainStatsFreeList(list);
+ QueryStatsFreeList(list);
return (err);
}
@@ -1412,15 +1728,15 @@ exit:
mDNSlocal mStatus CreateResolveStatsList(ResolveStatsDomain **outList)
{
mStatus err;
- int i;
+ unsigned int i;
ResolveStatsDomain * domain;
ResolveStatsDomain ** p;
ResolveStatsDomain * list = NULL;
p = &list;
- for (i = 0; i < (int)countof(kResolveStatsDomains); ++i)
+ for (i = 0; i < (unsigned int)countof(kResolveStatsDomains); ++i)
{
- err = ResolveStatsDomainCreate(&kResolveStatsDomains[i], &domain);
+ err = ResolveStatsDomainCreate(kResolveStatsDomains[i], &domain);
require_noerr_quiet(err, exit);
*p = domain;
@@ -1429,6 +1745,7 @@ mDNSlocal mStatus CreateResolveStatsList(ResolveStatsDomain **outList)
*outList = list;
list = NULL;
+ err = mStatus_NoError;
exit:
FreeResolveStatsList(list);
@@ -1491,7 +1808,11 @@ mDNSlocal mStatus SubmitAWDMetric(UInt32 inMetricID)
KQueueUnlock("SubmitAWDSimpleMetricServiceStats");
err = mStatus_NoError;
break;
-
+
+ case AWDMetricId_MDNSResponder_DNSMessageSizeStats:
+ err = SubmitAWDMetricDNSMessageSizeStats();
+ break;
+
default:
err = mStatus_UnsupportedErr;
break;
@@ -1505,22 +1826,25 @@ mDNSlocal mStatus SubmitAWDMetric(UInt32 inMetricID)
// SubmitAWDMetricQueryStats
//===========================================================================================================================
+mDNSlocal mStatus AddQueryStats(AWDMDNSResponderDNSStatistics *inMetric, const QueryStats *inStats);
+mDNSlocal mStatus AddDNSHistSet(AWDMDNSResponderDNSStatistics *inMetric, DNSHistSet *inSet, const char *inDomain, mDNSBool inForCell);
+
mDNSlocal mStatus SubmitAWDMetricQueryStats(void)
{
mStatus err;
BOOL success;
- DNSDomainStats * stats;
- DNSDomainStats * newDomainStatsList;
- DNSDomainStats * domainStatsList = NULL;
- AWDMetricContainer * container = nil;
- AWDMDNSResponderDNSStatistics * metric = nil;
+ QueryStats * stats;
+ QueryStats * statsList;
+ QueryStats * newStatsList;
+ AWDMetricContainer * container = nil;
+ AWDMDNSResponderDNSStatistics * metric = nil;
- err = CreateDomainStatsList(&newDomainStatsList);
- require_noerr_quiet(err, exit);
+ newStatsList = NULL;
+ CreateQueryStatsList(&newStatsList);
KQueueLock();
- domainStatsList = gDomainStatsList;
- gDomainStatsList = newDomainStatsList;
+ statsList = gQueryStatsList;
+ gQueryStatsList = newStatsList;
KQueueUnlock("SubmitAWDMetricQueryStats");
container = [gAWDServerConnection newMetricContainerWithIdentifier:AWDMetricId_MDNSResponder_DNSStatistics];
@@ -1529,31 +1853,71 @@ mDNSlocal mStatus SubmitAWDMetricQueryStats(void)
metric = [[AWDMDNSResponderDNSStatisticsSoft alloc] init];
require_action_quiet(metric, exit, err = mStatus_UnknownErr);
- while ((stats = domainStatsList) != NULL)
+ while ((stats = statsList) != NULL)
{
- if (stats->nonCellular)
- {
- err = AddAWDDNSDomainStats(metric, stats->nonCellular, stats->domain->cstr, mDNSfalse);
- require_noerr_quiet(err, exit);
- }
- if (stats->cellular)
- {
- err = AddAWDDNSDomainStats(metric, stats->cellular, stats->domain->cstr, mDNStrue);
- require_noerr_quiet(err, exit);
- }
- domainStatsList = stats->next;
- DNSDomainStatsFree(stats);
+ err = AddQueryStats(metric, stats);
+ require_noerr_quiet(err, exit);
+
+ statsList = stats->next;
+ QueryStatsFree(stats);
}
container.metric = metric;
success = [gAWDServerConnection submitMetric:container];
- LogMsg("SubmitAWDMetricQueryStats: metric submission %s.", success ? "succeeded" : "failed" );
+ LogMsg("SubmitAWDMetricQueryStats: metric submission %s.", success ? "succeeded" : "failed");
err = success ? mStatus_NoError : mStatus_UnknownErr;
exit:
[metric release];
[container release];
- DNSDomainStatsFreeList(domainStatsList);
+ QueryStatsFreeList(statsList);
+ return (err);
+}
+
+mDNSlocal mStatus AddQueryStats(AWDMDNSResponderDNSStatistics *inMetric, const QueryStats *inStats)
+{
+ mStatus err;
+
+ if (inStats->nonCellular)
+ {
+ err = AddDNSHistSet(inMetric, inStats->nonCellular, QueryStatsGetDomainString(inStats), mDNSfalse);
+ require_noerr_quiet(err, exit);
+ }
+ if (inStats->cellular)
+ {
+ err = AddDNSHistSet(inMetric, inStats->cellular, QueryStatsGetDomainString(inStats), mDNStrue);
+ require_noerr_quiet(err, exit);
+ }
+ err = mStatus_NoError;
+
+exit:
+ return (err);
+}
+
+mDNSlocal mStatus AddDNSHistSet(AWDMDNSResponderDNSStatistics *inMetric, DNSHistSet *inSet, const char *inDomain, mDNSBool inForCell)
+{
+ mStatus err;
+ AWDDNSDomainStats * awdStats;
+
+ if (inSet->histA)
+ {
+ err = CreateAWDDNSDomainStats(inSet->histA, inDomain, inForCell, AWDDNSDomainStats_RecordType_A, &awdStats);
+ require_noerr_quiet(err, exit);
+
+ [inMetric addStats:awdStats];
+ [awdStats release];
+ }
+ if (inSet->histAAAA)
+ {
+ err = CreateAWDDNSDomainStats(inSet->histAAAA, inDomain, inForCell, AWDDNSDomainStats_RecordType_AAAA, &awdStats);
+ require_noerr_quiet(err, exit);
+
+ [inMetric addStats:awdStats];
+ [awdStats release];
+ }
+ err = mStatus_NoError;
+
+exit:
return (err);
}
@@ -1619,7 +1983,7 @@ mDNSlocal mStatus SubmitAWDMetricResolveStats(void)
container.metric = metric;
success = [gAWDServerConnection submitMetric:container];
- LogMsg("SubmitAWDMetricResolveStats: metric submission %s.", success ? "succeeded" : "failed" );
+ LogMsg("SubmitAWDMetricResolveStats: metric submission %s.", success ? "succeeded" : "failed");
err = success ? mStatus_NoError : mStatus_UnknownErr;
exit:
@@ -1631,6 +1995,61 @@ exit:
}
//===========================================================================================================================
+// SubmitAWDMetricDNSMessageSizeStats
+//===========================================================================================================================
+
+mDNSlocal mStatus SubmitAWDMetricDNSMessageSizeStats(void)
+{
+ mStatus err;
+ DNSMessageSizeStats * stats;
+ DNSMessageSizeStats * newStats;
+ AWDMetricContainer * container;
+ AWDMDNSResponderDNSMessageSizeStats * metric = nil;
+ BOOL success;
+
+ newStats = NULL;
+ DNSMessageSizeStatsCreate(&newStats);
+
+ KQueueLock();
+ stats = gDNSMessageSizeStats;
+ gDNSMessageSizeStats = newStats;
+ KQueueUnlock("SubmitAWDMetricDNSMessageSizeStats");
+
+ container = [gAWDServerConnection newMetricContainerWithIdentifier:AWDMetricId_MDNSResponder_DNSMessageSizeStats];
+ require_action_quiet(container, exit, err = mStatus_UnknownErr);
+
+ metric = [[AWDMDNSResponderDNSMessageSizeStatsSoft alloc] init];
+ require_action_quiet(metric, exit, err = mStatus_UnknownErr);
+
+ if (stats)
+ {
+ size_t binCount;
+ uint32_t bins[Max(kQuerySizeBinCount, kResponseSizeBinCount)];
+
+ // Set query size counts.
+
+ binCount = CopyHistogramBins(bins, stats->querySizeBins, kQuerySizeBinCount);
+ [metric setQuerySizeCounts:bins count:(NSUInteger)binCount];
+
+ // Set response size counts.
+
+ binCount = CopyHistogramBins(bins, stats->responseSizeBins, kResponseSizeBinCount);
+ [metric setResponseSizeCounts:bins count:(NSUInteger)binCount];
+ }
+
+ container.metric = metric;
+ success = [gAWDServerConnection submitMetric:container];
+ LogMsg("SubmitAWDMetricDNSMessageSizeStats: metric submission %s.", success ? "succeeded" : "failed");
+ err = success ? mStatus_NoError : mStatus_UnknownErr;
+
+exit:
+ [metric release];
+ [container release];
+ if (stats) DNSMessageSizeStatsFree(stats);
+ return (err);
+}
+
+//===========================================================================================================================
// CreateAWDDNSDomainStats
//===========================================================================================================================
@@ -1639,12 +2058,9 @@ mDNSlocal mStatus CreateAWDDNSDomainStats(DNSHist *inHist, const char *inDomain,
mStatus err;
AWDDNSDomainStats * awdStats = nil;
NSString * domain = nil;
+ size_t binCount;
uint32_t sendCountBins[kQueryStatsSendCountBinCount];
uint32_t latencyBins[kQueryStatsLatencyBinCount];
- int i;
- unsigned int totalAnswered;
- unsigned int totalNegAnswered;
- unsigned int totalUnanswered;
awdStats = [[AWDDNSDomainStatsSoft alloc] init];
require_action_quiet(awdStats, exit, err = mStatus_UnknownErr);
@@ -1656,55 +2072,40 @@ mDNSlocal mStatus CreateAWDDNSDomainStats(DNSHist *inHist, const char *inDomain,
awdStats.networkType = inForCell ? AWDDNSDomainStats_NetworkType_Cellular : AWDDNSDomainStats_NetworkType_NonCellular;
awdStats.recordType = inType;
- totalAnswered = 0;
- for (i = 0; i < kQueryStatsSendCountBinCount; ++i)
- {
- sendCountBins[i] = inHist->answeredQuerySendCountBins[i];
- totalAnswered += inHist->answeredQuerySendCountBins[i];
- }
- [awdStats setAnsweredQuerySendCounts:sendCountBins count:kQueryStatsSendCountBinCount];
+ // Positively answered query send counts
- totalNegAnswered = 0;
- for (i = 0; i < kQueryStatsSendCountBinCount; ++i)
- {
- sendCountBins[i] = inHist->negAnsweredQuerySendCountBins[i];
- totalNegAnswered += inHist->negAnsweredQuerySendCountBins[i];
- }
- [awdStats setNegAnsweredQuerySendCounts:sendCountBins count:kQueryStatsSendCountBinCount];
+ binCount = CopyHistogramBins(sendCountBins, inHist->answeredQuerySendCountBins, kQueryStatsSendCountBinCount);
+ [awdStats setAnsweredQuerySendCounts:sendCountBins count:(NSUInteger)binCount];
- totalUnanswered = 0;
- for (i = 0; i < kQueryStatsSendCountBinCount; ++i)
- {
- sendCountBins[i] = inHist->unansweredQuerySendCountBins[i];
- totalUnanswered += inHist->unansweredQuerySendCountBins[i];
- }
- [awdStats setUnansweredQuerySendCounts:sendCountBins count:kQueryStatsSendCountBinCount];
+ // binCount > 1 means that at least one of the non-zero send count bins had a non-zero count, i.e., at least one query
+ // was sent out on the wire. In that case, include the associated latency bins as well.
- if (totalAnswered > inHist->answeredQuerySendCountBins[0])
+ if (binCount > 1)
{
- for (i = 0; i < kQueryStatsLatencyBinCount; ++i)
- {
- latencyBins[i] = inHist->responseLatencyBins[i];
- }
- [awdStats setResponseLatencyMs:latencyBins count:kQueryStatsLatencyBinCount];
+ binCount = CopyHistogramBins(latencyBins, inHist->responseLatencyBins, kQueryStatsLatencyBinCount);
+ [awdStats setResponseLatencyMs:latencyBins count:(NSUInteger)binCount];
}
- if (totalNegAnswered > inHist->negAnsweredQuerySendCountBins[0])
+ // Negatively answered query send counts
+
+ binCount = CopyHistogramBins(sendCountBins, inHist->negAnsweredQuerySendCountBins, kQueryStatsSendCountBinCount);
+ [awdStats setNegAnsweredQuerySendCounts:sendCountBins count:(NSUInteger)binCount];
+
+ if (binCount > 1)
{
- for (i = 0; i < kQueryStatsLatencyBinCount; ++i)
- {
- latencyBins[i] = inHist->negResponseLatencyBins[i];
- }
- [awdStats setNegResponseLatencyMs:latencyBins count:kQueryStatsLatencyBinCount];
+ binCount = CopyHistogramBins(latencyBins, inHist->negResponseLatencyBins, kQueryStatsLatencyBinCount);
+ [awdStats setNegResponseLatencyMs:latencyBins count:(NSUInteger)binCount];
}
- if (totalUnanswered > 0)
+ // Unanswered query send counts
+
+ binCount = CopyHistogramBins(sendCountBins, inHist->unansweredQuerySendCountBins, kQueryStatsSendCountBinCount);
+ [awdStats setUnansweredQuerySendCounts:sendCountBins count:(NSUInteger)binCount];
+
+ if (binCount > 1)
{
- for (i = 0; i < kQueryStatsLatencyBinCount; ++i)
- {
- latencyBins[i] = inHist->unansweredQueryDurationBins[i];
- }
- [awdStats setUnansweredQueryDurationMs:latencyBins count:kQueryStatsLatencyBinCount];
+ binCount = CopyHistogramBins(latencyBins, inHist->unansweredQueryDurationBins, kQueryStatsLatencyBinCount);
+ [awdStats setUnansweredQueryDurationMs:latencyBins count:(NSUInteger)binCount];
}
*outStats = awdStats;
@@ -1718,37 +2119,6 @@ exit:
}
//===========================================================================================================================
-// AddAWDDNSDomainStats
-//===========================================================================================================================
-
-mDNSlocal mStatus AddAWDDNSDomainStats(AWDMDNSResponderDNSStatistics *inMetric, DNSHistSet *inSet, const char *inDomain, mDNSBool inForCell)
-{
- mStatus err;
- AWDDNSDomainStats * awdStats;
-
- if (inSet->histA)
- {
- err = CreateAWDDNSDomainStats(inSet->histA, inDomain, inForCell, AWDDNSDomainStats_RecordType_A, &awdStats);
- require_noerr_quiet(err, exit);
-
- [inMetric addStats:awdStats];
- [awdStats release];
- }
- if (inSet->histAAAA)
- {
- err = CreateAWDDNSDomainStats(inSet->histAAAA, inDomain, inForCell, AWDDNSDomainStats_RecordType_AAAA, &awdStats);
- require_noerr_quiet(err, exit);
-
- [inMetric addStats:awdStats];
- [awdStats release];
- }
- err = mStatus_NoError;
-
-exit:
- return (err);
-}
-
-//===========================================================================================================================
// LogDNSHistSet
//===========================================================================================================================
@@ -1762,7 +2132,7 @@ mDNSlocal void LogDNSHistSet(const DNSHistSet *inSet, const char *inDomain, mDNS
// LogDNSHist
//===========================================================================================================================
-#define Percent(N, D) ((N) * 100) / (D), (((N) * 10000) / (D)) % 100
+#define Percent(N, D) (((N) * 100) / (D)), ((((N) * 10000) / (D)) % 100)
#define PercentFmt "%3u.%02u"
#define LogStat(LABEL, COUNT, ACCUMULATOR, TOTAL) \
LogMsgNoIdent("%s %5u " PercentFmt " " PercentFmt, (LABEL), (COUNT), Percent(COUNT, TOTAL), Percent(ACCUMULATOR, TOTAL))
@@ -1903,63 +2273,72 @@ mDNSlocal void LogDNSHistLatencies(const uint16_t inLatencyBins[kQueryStatsLaten
}
//===========================================================================================================================
-// ValidateDNSStatsDomains
+// LogDNSMessageSizeStats
//===========================================================================================================================
-#if (METRICS_VALIDATE_DNS_STATS_DOMAINS)
-#warning "Do not include ValidateDNSStatsDomains() in customer release!"
-mDNSlocal void ValidateDNSStatsDomains(void)
+mDNSlocal void LogDNSMessageSizeStats(const uint16_t *inBins, size_t inBinCount, unsigned int inBinWidth)
{
- int i;
- const Domain * domain;
- mDNSu8 * ptr;
- domainname domainNameExpected;
- int labelCountExpected;
- mDNSBool domainNamesEqual;
- mDNSBool failed = mDNSfalse;
+ size_t i;
+ uint32_t total;
- for (i = 0; i < countof(kQueryStatsDomains); ++i)
+ total = 0;
+ for (i = 0; i < inBinCount; ++i)
{
- domain = &kQueryStatsDomains[i];
+ total += inBins[i];
+ }
- if (strcmp(domain->cstr, ".") == 0)
- {
- domainNameExpected.c[0] = 0;
- }
- else
- {
- ptr = MakeDomainNameFromDNSNameString(&domainNameExpected, domain->cstr);
- if (!ptr)
- {
- LogMsg("ValidateDNSStatsDomains: Failed to make domain name for \"%s\".", domain->cstr);
- failed = mDNStrue;
- goto exit;
- }
- }
+ if (total > 0)
+ {
+ uint32_t accumulator;
+ unsigned int lower, upper;
+ char label[16];
- domainNamesEqual = SameDomainName(domain->name, &domainNameExpected);
- labelCountExpected = CountLabels(&domainNameExpected);
- if (domainNamesEqual && (domain->labelCount == labelCountExpected))
- {
- LogMsg("ValidateDNSStatsDomains: \"%s\" passed.", domain->cstr);
- }
- else
+ accumulator = 0;
+ upper = 0;
+ for (i = 0; i < inBinCount; ++i)
{
- if (!domainNamesEqual)
+ accumulator += inBins[i];
+ lower = upper + 1;
+ if (i < (inBinCount - 1))
{
- LogMsg("ValidateDNSStatsDomains: \"%s\" failed: incorrect domain name.", domain->cstr);
+ upper += inBinWidth;
+ snprintf(label, sizeof(label), "%3u - %-3u", lower, upper);
}
- if (domain->labelCount != labelCountExpected)
+ else
{
- LogMsg("ValidateDNSStatsDomains: \"%s\" failed: incorrect label count. Actual %d, expected %d.",
- domain->cstr, domain->labelCount, labelCountExpected);
+ snprintf(label, sizeof(label), "%3u+ ", lower);
}
- failed = mDNStrue;
+ LogStat(label, inBins[i], accumulator, total);
+ if (accumulator == total) break;
}
}
+ else
+ {
+ LogMsgNoIdent("No data.");
+ }
+}
-exit:
- if (failed) abort();
+//===========================================================================================================================
+// CopyHistogramBins
+//
+// Note: The return value is the size (in number of elements) of the smallest contiguous sub-array that contains the first
+// bin and all bins with non-zero values.
+//===========================================================================================================================
+
+mDNSlocal size_t CopyHistogramBins(uint32_t *inDstBins, uint16_t *inSrcBins, size_t inBinCount)
+{
+ size_t i;
+ size_t minCount;
+
+ if (inBinCount == 0) return (0);
+
+ minCount = 1;
+ for (i = 0; i < inBinCount; ++i)
+ {
+ inDstBins[i] = inSrcBins[i];
+ if (inDstBins[i] > 0) minCount = i + 1;
+ }
+
+ return (minCount);
}
-#endif
-#endif // TARGET_OS_EMBEDDED
+#endif // TARGET_OS_IOS
diff --git a/mDNSResponder/mDNSMacOSX/daemon.c b/mDNSResponder/mDNSMacOSX/daemon.c
index 5dece763..fa192b6a 100644
--- a/mDNSResponder/mDNSMacOSX/daemon.c
+++ b/mDNSResponder/mDNSMacOSX/daemon.c
@@ -45,7 +45,7 @@
#include "xpc_services.h" // Interface to XPC services
#include "helper.h"
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
#include "Metrics.h"
#endif
@@ -558,7 +558,7 @@ mDNSexport void INFOCallback(void)
LogMsgNoIdent("%##s", mDNSStorage.FQDN.c);
}
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
LogMetrics();
#endif
LogMsgNoIdent("Timenow 0x%08lX (%d)", (mDNSu32)now, now);
@@ -1360,9 +1360,10 @@ mDNSlocal void * KQueueLoop(void *m_param)
{
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;
@@ -1390,7 +1391,7 @@ mDNSlocal size_t LaunchdCheckin(void)
{
// 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;
}
@@ -1620,14 +1621,26 @@ mDNSexport int main(int argc, char **argv)
// 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
@@ -1644,7 +1657,7 @@ mDNSexport int main(int argc, char **argv)
#endif
SandboxProcess();
-#if TARGET_OS_EMBEDDED
+#if AWD_METRICS
status = MetricsInit();
if (status) { LogMsg("Daemon start: MetricsInit failed (%d)", status); }
#endif
@@ -1666,7 +1679,7 @@ mDNSexport int main(int argc, char **argv)
// 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();
diff --git a/mDNSResponder/mDNSMacOSX/helper.c b/mDNSResponder/mDNSMacOSX/helper.c
index f5b4f3b2..dc90b35d 100644
--- a/mDNSResponder/mDNSMacOSX/helper.c
+++ b/mDNSResponder/mDNSMacOSX/helper.c
@@ -1456,15 +1456,17 @@ void RetrieveTCPInfo(int family, const v6addr_t laddr, uint16_t lport, const v6a
sz = sizeof(mib)/sizeof(mib[0]);
if (sysctlnametomib("net.inet.tcp.info", mib, &sz) == -1)
{
- os_log(log_handle, "RetrieveTCPInfo: sysctlnametomib failed %d, %s", errno, strerror(errno));
- *err = errno;
+ const int sysctl_errno = errno;
+ os_log(log_handle, "RetrieveTCPInfo: sysctlnametomib failed %d, %s", sysctl_errno, strerror(sysctl_errno));
+ *err = sysctl_errno;
}
miblen = (unsigned int)sz;
len = sizeof(struct tcp_info);
if (sysctl(mib, miblen, &ti, &len, &itpl, sizeof(struct info_tuple)) == -1)
{
- os_log(log_handle, "RetrieveTCPInfo: sysctl failed %d, %s", errno, strerror(errno));
- *err = errno;
+ const int sysctl_errno = errno;
+ os_log(log_handle, "RetrieveTCPInfo: sysctl failed %d, %s", sysctl_errno, strerror(sysctl_errno));
+ *err = sysctl_errno;
}
*seq = ti.tcpi_snd_nxt - 1;
@@ -1745,8 +1747,9 @@ static int startRacoon(void)
}
else if (result < 0)
{
- os_log_debug(log_handle, "select returned %d errno %d %s", result, errno, strerror(errno));
- if (errno != EINTR) break;
+ const int select_errno = errno;
+ os_log_debug(log_handle, "select returned %d errno %d %s", result, select_errno, strerror(select_errno));
+ if (select_errno != EINTR) break;
}
}
@@ -1827,7 +1830,7 @@ static int setupTunnelRoute(const v6addr_t local, const v6addr_t remote)
/* send message, ignore error when route already exists */
if (0 > write(s, &msg, msg.hdr.rtm_msglen))
{
- int errno_ = errno;
+ const int errno_ = errno;
os_log_info(log_handle,"write to routing socket failed: %s", strerror(errno_));
if (EEXIST != errno_)
@@ -1872,7 +1875,7 @@ static int teardownTunnelRoute(const v6addr_t remote)
memcpy(&msg.dst.sin6_addr, remote, sizeof(msg.dst.sin6_addr));
if (0 > write(s, &msg, msg.hdr.rtm_msglen))
{
- int errno_ = errno;
+ const int errno_ = errno;
os_log_debug(log_handle,"write to routing socket failed: %s", strerror(errno_));
diff --git a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
index ced72a69..3bb4ec69 100644
--- a/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
+++ b/mDNSResponder/mDNSMacOSX/mDNSMacOSX.c
@@ -661,6 +661,7 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
struct sockaddr_storage to;
int s = -1, err;
mStatus result = mStatus_NoError;
+ int sendto_errno;
if (InterfaceID)
{
@@ -736,9 +737,10 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
err = setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, &info->scope_id, sizeof(info->scope_id));
if (err < 0)
{
+ const int setsockopt_errno = errno;
char name[IFNAMSIZ];
if (if_indextoname(info->scope_id, name) != NULL)
- LogMsg("setsockopt - IPV6_MULTICAST_IF error %d errno %d (%s)", err, errno, strerror(errno));
+ LogMsg("setsockopt - IPV6_MULTICAST_IF error %d errno %d (%s)", err, setsockopt_errno, strerror(setsockopt_errno));
else
LogInfo("setsockopt - IPV6_MUTLICAST_IF scopeid %d, not a valid interface", info->scope_id);
}
@@ -779,6 +781,7 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
setTrafficClass(s, useBackgroundTrafficClass);
err = sendto(s, msg, (UInt8*)end - (UInt8*)msg, 0, (struct sockaddr *)&to, to.ss_len);
+ sendto_errno = (err < 0) ? errno : 0;
// set traffic class back to default value
if (useBackgroundTrafficClass)
@@ -788,30 +791,30 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
{
static int MessageCount = 0;
LogInfo("mDNSPlatformSendUDP -> sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu",
- s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, sendto_errno, strerror(sendto_errno), (mDNSu32)(m->timenow));
if (!mDNSAddressIsAllDNSLinkGroup(dst))
{
- if (errno == EHOSTUNREACH) return(mStatus_HostUnreachErr);
- if (errno == EHOSTDOWN || errno == ENETDOWN || errno == ENETUNREACH) return(mStatus_TransientErr);
+ if (sendto_errno == EHOSTUNREACH) return(mStatus_HostUnreachErr);
+ if (sendto_errno == EHOSTDOWN || sendto_errno == ENETDOWN || sendto_errno == ENETUNREACH) return(mStatus_TransientErr);
}
// Don't report EHOSTUNREACH in the first three minutes after boot
// This is because mDNSResponder intentionally starts up early in the boot process (See <rdar://problem/3409090>)
// but this means that sometimes it starts before configd has finished setting up the multicast routing entries.
- if (errno == EHOSTUNREACH && (mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180)) return(mStatus_TransientErr);
+ if (sendto_errno == EHOSTUNREACH && (mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180)) return(mStatus_TransientErr);
// Don't report EADDRNOTAVAIL ("Can't assign requested address") if we're in the middle of a network configuration change
- if (errno == EADDRNOTAVAIL && m->NetworkChanged) return(mStatus_TransientErr);
- if (errno == EHOSTUNREACH || errno == EADDRNOTAVAIL || errno == ENETDOWN)
+ if (sendto_errno == EADDRNOTAVAIL && m->NetworkChanged) return(mStatus_TransientErr);
+ if (sendto_errno == EHOSTUNREACH || sendto_errno == EADDRNOTAVAIL || sendto_errno == ENETDOWN)
LogInfo("mDNSPlatformSendUDP sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu",
- s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow));
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, sendto_errno, strerror(sendto_errno), (mDNSu32)(m->timenow));
else
{
MessageCount++;
if (MessageCount < 50) // Cap and ensure NO spamming of LogMsgs
LogMsg("mDNSPlatformSendUDP: sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu MessageCount is %d",
- s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow), MessageCount);
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, sendto_errno, strerror(sendto_errno), (mDNSu32)(m->timenow), MessageCount);
else // If logging is enabled, remove the cap and log aggressively
LogInfo("mDNSPlatformSendUDP: sendto(%d) failed to send packet on InterfaceID %p %5s/%d to %#a:%d skt %d error %d errno %d (%s) %lu MessageCount is %d",
- s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, errno, strerror(errno), (mDNSu32)(m->timenow), MessageCount);
+ s, InterfaceID, ifa_name, dst->type, dst, mDNSVal16(dstPort), s, err, sendto_errno, strerror(sendto_errno), (mDNSu32)(m->timenow), MessageCount);
}
result = mStatus_UnknownErr;
@@ -1071,7 +1074,7 @@ mDNSexport void myKQSocketCallBack(int s1, short filter, void *context, mDNSBool
// Find out about other socket parameter that can help understand why select() says the socket is ready for read
// All of this is racy, as data may have arrived after the call to select()
static unsigned int numLogMessages = 0;
- int save_errno = errno;
+ const int save_errno = errno;
int so_error = -1;
int so_nread = -1;
int fionread = -1;
@@ -1912,6 +1915,7 @@ mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa
mStatus err = mStatus_NoError;
char *errstr = mDNSNULL;
const int mtu = 0;
+ int saved_errno;
cp->closeFlag = mDNSNULL;
@@ -2044,12 +2048,13 @@ mDNSlocal mStatus SetupSocket(KQSocketSet *cp, const mDNSIPPort port, u_short sa
return(mStatus_NoError);
fail:
+ saved_errno = errno;
// For "bind" failures, only write log messages for our shared mDNS port, or for binding to zero
if (strcmp(errstr, "bind") || mDNSSameIPPort(port, MulticastDNSPort) || mDNSIPPortIsZero(port))
- LogMsg("%s skt %d port %d error %d errno %d (%s)", errstr, skt, mDNSVal16(port), err, errno, strerror(errno));
+ LogMsg("%s skt %d port %d error %d errno %d (%s)", errstr, skt, mDNSVal16(port), err, saved_errno, strerror(saved_errno));
// If we got a "bind" failure of EADDRINUSE, inform the caller as it might need to try another random port
- if (!strcmp(errstr, "bind") && errno == EADDRINUSE)
+ if (!strcmp(errstr, "bind") && saved_errno == EADDRINUSE)
{
err = EADDRINUSE;
if (mDNSSameIPPort(port, MulticastDNSPort))
@@ -2325,8 +2330,9 @@ cp += len; \
sock = socket(PF_ROUTE, SOCK_RAW, 0);
if (sock < 0)
{
- LogMsg("getMACAddress: Can not open the socket - %s", strerror(errno));
- return errno;
+ const int socket_errno = errno;
+ LogMsg("getMACAddress: Can not open the socket - %s", strerror(socket_errno));
+ return socket_errno;
}
rtm->rtm_addrs |= RTA_DST | RTA_GATEWAY;
@@ -2358,9 +2364,10 @@ cp += len; \
if (write(sock, (char *)&m_rtmsg, rlen) < 0)
{
- LogMsg("getMACAddress: writing to routing socket: %s", strerror(errno));
+ const int write_errno = errno;
+ LogMsg("getMACAddress: writing to routing socket: %s", strerror(write_errno));
close(sock);
- return errno;
+ return write_errno;
}
do
@@ -3235,7 +3242,11 @@ mDNSlocal mDNSBool InterfaceSupportsKeepAlive(NetworkInterfaceInfo *const intf)
mDNSlocal mDNSBool NetWakeInterface(NetworkInterfaceInfoOSX *i)
{
// We only use Sleep Proxy Service on multicast-capable interfaces, except loopback and D2D.
- if (!SPSInterface(i)) return(mDNSfalse);
+ if (!MulticastInterface(i) || (i->ifa_flags & IFF_LOOPBACK) || i->D2DInterface)
+ {
+ LogSPS("NetWakeInterface: returning false for %s", i->ifinfo.ifname);
+ return(mDNSfalse);
+ }
// If the interface supports TCPKeepalive, it is capable of waking up for a magic packet
// This check is needed since the SIOCGIFWAKEFLAGS ioctl returns wrong values for WOMP capability
@@ -3253,15 +3264,16 @@ mDNSlocal mDNSBool NetWakeInterface(NetworkInterfaceInfoOSX *i)
strlcpy(ifr.ifr_name, i->ifinfo.ifname, sizeof(ifr.ifr_name));
if (ioctl(s, SIOCGIFWAKEFLAGS, &ifr) < 0)
{
+ const int ioctl_errno = errno;
// For some strange reason, in /usr/include/sys/errno.h, EOPNOTSUPP is defined to be
// 102 when compiling kernel code, and 45 when compiling user-level code. Since this
// error code is being returned from the kernel, we need to use the kernel version.
#define KERNEL_EOPNOTSUPP 102
- if (errno != KERNEL_EOPNOTSUPP) // "Operation not supported on socket", the expected result on Leopard and earlier
- LogMsg("NetWakeInterface SIOCGIFWAKEFLAGS %s errno %d (%s)", i->ifinfo.ifname, errno, strerror(errno));
+ if (ioctl_errno != KERNEL_EOPNOTSUPP) // "Operation not supported on socket", the expected result on Leopard and earlier
+ LogMsg("NetWakeInterface SIOCGIFWAKEFLAGS %s errno %d (%s)", i->ifinfo.ifname, ioctl_errno, strerror(ioctl_errno));
// If on Leopard or earlier, we get EOPNOTSUPP, so in that case
// we enable WOL if this interface is not AirPort and "Wake for Network access" is turned on.
- ifr.ifr_wake_flags = (errno == KERNEL_EOPNOTSUPP && !(i)->BSSID.l[0] && i->m->SystemWakeOnLANEnabled) ? IF_WAKE_ON_MAGIC_PACKET : 0;
+ ifr.ifr_wake_flags = (ioctl_errno == KERNEL_EOPNOTSUPP && !(i)->BSSID.l[0] && i->m->SystemWakeOnLANEnabled) ? IF_WAKE_ON_MAGIC_PACKET : 0;
}
close(s);
diff --git a/mDNSResponder/mDNSShared/dns_sd.h b/mDNSResponder/mDNSShared/dns_sd.h
index 41a2bc39..0b47c394 100644
--- a/mDNSResponder/mDNSShared/dns_sd.h
+++ b/mDNSResponder/mDNSShared/dns_sd.h
@@ -66,7 +66,7 @@
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 8782003
+#define _DNS_SD_H 8783004
#ifdef __cplusplus
extern "C" {