diff --git a/src/tools/mdnssd/DNSCommon.c b/src/tools/mdnssd/DNSCommon.c
index 3ec6e3851915e307fa54b5cc1213037ee7137e51..e526068339376d5531e58df93b1f201a40671560 100644
--- a/src/tools/mdnssd/DNSCommon.c
+++ b/src/tools/mdnssd/DNSCommon.c
@@ -1369,12 +1369,20 @@ mDNSexport mDNSBool AnyTypeRecordAnswersQuestion(const ResourceRecord *const rr,
 	return(rr->namehash == q->qnamehash && SameDomainName(rr->name, &q->qname));
 	}
 
-// This is called only when the caller knows that it is a Unicast Resource Record and it is a Unicast Question
-// and hence we don't need InterfaceID checks like above. Though this may not be a big optimization, the main
-// reason we need this is that we can't compare DNSServers between the question and the resource record because
-// the resource record may not be completely initialized e.g., mDNSCoreReceiveResponse
-mDNSexport mDNSBool UnicastResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q)
-	{
+// This is called with both unicast resource record and multicast resource record. The question that
+// received the unicast response could be the regular unicast response from a DNS server or a response
+// to a mDNS QU query. The main reason we need this function is that we can't compare DNSServers between the
+// question and the resource record because the resource record is not completely initialized in
+// mDNSCoreReceiveResponse when this function is called.
+mDNSexport mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q)
+	{
+	// For resource records created using multicast, the InterfaceIDs have to match
+	if (rr->InterfaceID &&
+		q->InterfaceID && rr->InterfaceID != q->InterfaceID) return(mDNSfalse);
+
+	// If ResourceRecord received via multicast, but question was unicast, then shouldn't use record to answer this question.
+	if (rr->InterfaceID && !mDNSOpaque16IsZero(q->TargetQID)) return(mDNSfalse);
+
 	// RR type CNAME matches any query type. QTYPE ANY matches any RR type. QCLASS ANY matches any RR class.
 	if (!RRTypeAnswersQuestionType(rr,q->qtype)) return(mDNSfalse);
 
diff --git a/src/tools/mdnssd/DNSCommon.h b/src/tools/mdnssd/DNSCommon.h
index 08c636d9c7536faffef6a5690b8632d1bae0b855..5df4ce410d9329b48166abae695126a22958b227 100644
--- a/src/tools/mdnssd/DNSCommon.h
+++ b/src/tools/mdnssd/DNSCommon.h
@@ -164,7 +164,7 @@ extern mDNSBool SameRDataBody(const ResourceRecord *const r1, const RDataBody *c
 extern mDNSBool SameNameRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
 extern mDNSBool ResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
 extern mDNSBool AnyTypeRecordAnswersQuestion (const ResourceRecord *const rr, const DNSQuestion *const q);
-extern mDNSBool UnicastResourceRecordAnswersQuestion(const ResourceRecord *const rr, const DNSQuestion *const q);
+extern mDNSBool ResourceRecordAnswersUnicastResponse(const ResourceRecord *const rr, const DNSQuestion *const q);
 extern mDNSBool LocalOnlyRecordAnswersQuestion(AuthRecord *const rr, const DNSQuestion *const q);
 extern mDNSu16 GetRDLength(const ResourceRecord *const rr, mDNSBool estimate);
 extern mDNSBool ValidateRData(const mDNSu16 rrtype, const mDNSu16 rdlength, const RData *const rd);
diff --git a/src/tools/mdnssd/DNSDigest.c b/src/tools/mdnssd/DNSDigest.c
index b4a0158cc336db45fd407698cbcc4366b0d2b74c..98d23dbdd1117b052beff35be969398580d852a5 100644
--- a/src/tools/mdnssd/DNSDigest.c
+++ b/src/tools/mdnssd/DNSDigest.c
@@ -1,6 +1,6 @@
 /* -*- Mode: C; tab-width: 4 -*-
  *
- * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2011 Apple Computer, 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.
@@ -571,9 +571,16 @@ void md5_block_data_order (MD5_CTX *c, const void *p,int num);
 #endif
 #endif
 
+// None of the invocations of the following macros actually use the result,
+// so cast them to void to avoid any compiler warnings/errors about not using
+// the result (e.g. when using clang).
+// If the resultant values need to be used at some point, these must be changed.
+#define HOST_c2l(c,l) ((void)_HOST_c2l(c,l))
+#define HOST_l2c(l,c) ((void)_HOST_l2c(l,c))
+
 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
 
-#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
+#define _HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))<<24),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
 			 l|=(((unsigned long)(*((c)++)))    ),		\
@@ -601,7 +608,7 @@ void md5_block_data_order (MD5_CTX *c, const void *p,int num);
 			case 2: l|=((unsigned long)(*(--(c))))<<16;	\
 			case 1: l|=((unsigned long)(*(--(c))))<<24;	\
 				} }
-#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
+#define _HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)>>24)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)    )&0xff),	\
@@ -609,7 +616,7 @@ void md5_block_data_order (MD5_CTX *c, const void *p,int num);
 
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
 
-#define HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
+#define _HOST_c2l(c,l)	(l =(((unsigned long)(*((c)++)))    ),		\
 			 l|=(((unsigned long)(*((c)++)))<< 8),		\
 			 l|=(((unsigned long)(*((c)++)))<<16),		\
 			 l|=(((unsigned long)(*((c)++)))<<24),		\
@@ -637,7 +644,7 @@ void md5_block_data_order (MD5_CTX *c, const void *p,int num);
 			case 2: l|=((unsigned long)(*(--(c))))<< 8;	\
 			case 1: l|=((unsigned long)(*(--(c))));		\
 				} }
-#define HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
+#define _HOST_l2c(l,c)	(*((c)++)=(unsigned char)(((l)    )&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>> 8)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>16)&0xff),	\
 			 *((c)++)=(unsigned char)(((l)>>24)&0xff),	\
diff --git a/src/tools/mdnssd/dns_sd.h b/src/tools/mdnssd/dns_sd.h
index 5416a604c6fc5c0788d14450d016daaf9c0d0ddb..3caa6a85865e7cb5251135d53a24a5fe224790fa 100644
--- a/src/tools/mdnssd/dns_sd.h
+++ b/src/tools/mdnssd/dns_sd.h
@@ -77,7 +77,7 @@
  */
 
 #ifndef _DNS_SD_H
-#define _DNS_SD_H 3200500
+#define _DNS_SD_H 3331000
 
 #ifdef  __cplusplus
     extern "C" {
diff --git a/src/tools/mdnssd/dnssd_ipc.h b/src/tools/mdnssd/dnssd_ipc.h
index d41edc8725257619f6a38475a6a3a1d739ede9fc..748bbdf2139f62ee170958254a07e374c423bb32 100644
--- a/src/tools/mdnssd/dnssd_ipc.h
+++ b/src/tools/mdnssd/dnssd_ipc.h
@@ -152,7 +152,7 @@ typedef enum
     } reply_op_t;
 
 #if defined(_WIN64)
-#	pragma pack(4)
+#	pragma pack(push,4)
 #endif
 
 // Define context object big enough to hold a 64-bit pointer,
@@ -176,6 +176,10 @@ typedef packedstruct
     // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
     } ipc_msg_hdr;
 
+#if defined(_WIN64)
+#	pragma pack(pop)
+#endif
+
 // routines to write to and extract data from message buffers.
 // caller responsible for bounds checking.
 // ptr is the address of the pointer to the start of the field.
diff --git a/src/tools/mdnssd/mDNS.c b/src/tools/mdnssd/mDNS.c
old mode 100755
new mode 100644
index 11c66715bb07710d14d42ea9a2cd11390e414de0..9de7f92c181e52d18396ca86ded4b193cf557508
--- a/src/tools/mdnssd/mDNS.c
+++ b/src/tools/mdnssd/mDNS.c
@@ -349,7 +349,7 @@ mDNSexport mDNSBool mDNS_AddressIsLocalSubnet(mDNS *const m, const mDNSInterface
 
 	if (addr->type == mDNSAddrType_IPv6)
 		{
-		if (mDNSv6AddressIsLinkLocal(&addr->ip.v4)) return(mDNStrue);
+		if (mDNSv6AddressIsLinkLocal(&addr->ip.v6)) return(mDNStrue);
 		for (intf = m->HostInterfaces; intf; intf = intf->next)
 			if (intf->ip.type == addr->type && intf->InterfaceID == InterfaceID && intf->McastTxRx)
 				if ((((intf->ip.ip.v6.l[0] ^ addr->ip.v6.l[0]) & intf->mask.ip.v6.l[0]) == 0) &&
@@ -1730,7 +1730,7 @@ mDNSlocal void SendDelayedUnicastResponse(mDNS *const m, const mDNSAddr *const d
 			}
 
 		if (m->omsg.h.numAnswers)
-			mDNSSendDNSMessage(m, &m->omsg, responseptr, mDNSInterface_Any, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
+			mDNSSendDNSMessage(m, &m->omsg, responseptr, InterfaceID, mDNSNULL, dest, MulticastDNSPort, mDNSNULL, mDNSNULL);
 		}
 	}
 
@@ -3285,6 +3285,22 @@ mDNSlocal void SendWakeup(mDNS *const m, mDNSInterfaceID InterfaceID, mDNSEthAdd
 #pragma mark - RR List Management & Task Management
 #endif
 
+// Whenever a question is answered, reset its state so that we don't query
+// the network repeatedly. This happens first time when we answer the question and
+// and later when we refresh the cache.
+mDNSlocal void ResetQuestionState(mDNS *const m, DNSQuestion *q)
+	{
+	q->LastQTime		= m->timenow;
+	q->LastQTxTime	  = m->timenow;
+	q->RecentAnswerPkts = 0;
+	q->ThisQInterval	= MaxQuestionInterval;
+	q->RequestUnicast   = mDNSfalse;
+	// Reset unansweredQueries so that we don't penalize this server later when we
+	// start sending queries when the cache expires.
+	q->unansweredQueries = 0;
+	debugf("ResetQuestionState: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+	}
+
 // Note: AnswerCurrentQuestionWithResourceRecord can call a user callback, which may change the record list and/or question list.
 // Any code walking either list must use the m->CurrentQuestion (and possibly m->CurrentRecord) mechanism to protect against this.
 // In fact, to enforce this, the routine will *only* answer the question currently pointed to by m->CurrentQuestion,
@@ -3343,12 +3359,7 @@ mDNSexport void AnswerCurrentQuestionWithResourceRecord(mDNS *const m, CacheReco
 		(AddRecord == QC_add && (q->ExpectUnique || (rr->resrec.RecordType & kDNSRecordTypePacketUniqueMask))))
 		if (ActiveQuestion(q) && (mDNSOpaque16IsZero(q->TargetQID) || !q->LongLived))
 			{
-			q->LastQTime        = m->timenow;
-			q->LastQTxTime      = m->timenow;
-			q->RecentAnswerPkts = 0;
-			q->ThisQInterval    = MaxQuestionInterval;
-			q->RequestUnicast   = mDNSfalse;
-			debugf("AnswerCurrentQuestionWithResourceRecord: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
+			ResetQuestionState(m, q);
 			}
 
 	if (rr->DelayDelivery) return;		// We'll come back later when CacheRecordDeferredAdd() calls us
@@ -6278,6 +6289,8 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForQuestion(const mDNS *const m,
 	return(mDNSNULL);
 	}
 
+// This function is called when we receive a unicast response. This could be the case of a unicast response from the
+// DNS server or a response to the QU query. Hence, the cache record's InterfaceId can be both NULL or non-NULL (QU case)
 mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
 	const mDNSAddr *const srcaddr, const mDNSBool SrcLocal, const mDNSIPPort port, const mDNSOpaque16 id, const CacheRecord *const rr, mDNSBool tcp)
 	{
@@ -6285,12 +6298,9 @@ mDNSlocal DNSQuestion *ExpectingUnicastResponseForRecord(mDNS *const m,
 	(void)id;
 	(void)srcaddr;
 
-	// Unicast records have zero as InterfaceID
-	if (rr->resrec.InterfaceID) return mDNSNULL;
-
 	for (q = m->Questions; q; q=q->next)
 		{
-		if (!q->DuplicateOf && UnicastResourceRecordAnswersQuestion(&rr->resrec, q))
+		if (!q->DuplicateOf && ResourceRecordAnswersUnicastResponse(&rr->resrec, q))
 			{
 			if (!mDNSOpaque16IsZero(q->TargetQID))
 				{
@@ -6867,12 +6877,7 @@ mDNSlocal void mDNSCoreReceiveResponse(mDNS *const m,
 								if (!q->DuplicateOf && !q->LongLived &&
 									ActiveQuestion(q) && ResourceRecordAnswersQuestion(&rr->resrec, q))
 									{
-									q->LastQTime        = m->timenow;
-									q->LastQTxTime      = m->timenow;
-									q->RecentAnswerPkts = 0;
-									q->ThisQInterval    = MaxQuestionInterval;
-									q->RequestUnicast   = mDNSfalse;
-									q->unansweredQueries = 0;
+									ResetQuestionState(m, q);
 									debugf("mDNSCoreReceiveResponse: Set MaxQuestionInterval for %p %##s (%s)", q, q->qname.c, DNSTypeName(q->qtype));
 									break;		// Why break here? Aren't there other questions we might want to look at?-- SC July 2010
 									}
@@ -7146,8 +7151,14 @@ exit:
 					// If we already had a negative cache entry just update it, else make one or more new negative cache entries
 					if (neg)
 						{
-						debugf("Renewing negative TTL from %d to %d %s", neg->resrec.rroriginalttl, negttl, CRDisplayString(m, neg));
+						debugf("mDNSCoreReceiveResponse: Renewing negative TTL from %d to %d %s", neg->resrec.rroriginalttl, negttl, CRDisplayString(m, neg));
 						RefreshCacheRecord(m, neg, negttl);
+						// When we created the cache for the first time and answered the question, the question's
+						// interval was set to MaxQuestionInterval. If the cache is about to expire and we are resending
+						// the queries, the interval should still be at MaxQuestionInterval. If the query is being
+						// restarted (setting it to InitialQuestionInterval) for other reasons e.g., wakeup,
+						// we should reset its question interval here to MaxQuestionInterval.
+						ResetQuestionState(m, qptr);
 						}
 					else while (1)
 						{
@@ -7817,6 +7828,55 @@ mDNSlocal mDNSu32 GetTimeoutForMcastQuestion(mDNS *m, DNSQuestion *question)
 	return ( curmatch ? curmatch->timeout : DEFAULT_MCAST_TIMEOUT);
 	}
 
+// Returns true if it is a Domain Enumeration Query
+mDNSexport mDNSBool DomainEnumQuery(const domainname *qname)
+	{
+	const mDNSu8 *mDNS_DEQLabels[] = { (const mDNSu8 *)"\001b", (const mDNSu8 *)"\002db", (const mDNSu8 *)"\002lb",
+		(const mDNSu8 *)"\001r", (const mDNSu8 *)"\002dr", (const mDNSu8 *)mDNSNULL, };
+	const domainname *d = qname;
+	const mDNSu8 *label;
+	int i = 0;
+
+	// We need at least 3 labels (DEQ prefix) + one more label to make a meaningful DE query
+	if (CountLabels(qname) < 4) { debugf("DomainEnumQuery: question %##s, not enough labels", qname->c); return mDNSfalse; }
+
+	label = (const mDNSu8 *)d;
+	while (mDNS_DEQLabels[i] != (const mDNSu8 *)mDNSNULL)
+		{
+		if (SameDomainLabel(mDNS_DEQLabels[i], label)) {debugf("DomainEnumQuery: DEQ %##s, label1 match", qname->c); break;}
+		i++;
+		}
+	if (mDNS_DEQLabels[i] == (const mDNSu8 *)mDNSNULL)
+		{
+		debugf("DomainEnumQuery: Not a DEQ %##s, label1 mismatch", qname->c);
+		return mDNSfalse;
+		}
+	debugf("DomainEnumQuery: DEQ %##s, label1 match", qname->c);
+
+	// CountLabels already verified the number of labels
+	d = (const domainname *)(d->c + 1 + d->c[0]);	// Second Label
+	label = (const mDNSu8 *)d;
+	if (!SameDomainLabel(label, (const mDNSu8 *)"\007_dns-sd"))
+		{
+		debugf("DomainEnumQuery: Not a DEQ %##s, label2 mismatch", qname->c);
+		return(mDNSfalse);
+		}
+	debugf("DomainEnumQuery: DEQ %##s, label2 match", qname->c);
+
+	d = (const domainname *)(d->c + 1 + d->c[0]); 	// Third Label
+	label = (const mDNSu8 *)d;
+	if (!SameDomainLabel(label, (const mDNSu8 *)"\004_udp"))
+		{
+		debugf("DomainEnumQuery: Not a DEQ %##s, label3 mismatch", qname->c);
+		return(mDNSfalse);
+		}
+	debugf("DomainEnumQuery: DEQ %##s, label3 match", qname->c);
+
+	debugf("DomainEnumQuery: Question %##s is a Domain Enumeration query", qname->c);
+
+	return mDNStrue;
+	}
+
 // Sets all the Valid DNS servers for a question
 mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
 	{
@@ -7826,8 +7886,10 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
 	int bettermatch, currcount;
 	int index = 0;
 	mDNSu32 timeout = 0;
+	mDNSBool DEQuery;
 
 	question->validDNSServers = zeroOpaque64;
+	DEQuery = DomainEnumQuery(&question->qname);
 	for (curr = m->DNSServers; curr; curr = curr->next)
 		{
 		debugf("SetValidDNSServers: Parsing DNS server Address %#a (Domain %##s), Scope: %d", &curr->addr, curr->domain.c, curr->scoped);
@@ -7847,7 +7909,9 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
 			{ debugf("SetValidDNSServers: Scoped DNS server %#a (Domain %##s) with Interface Any", &curr->addr, curr->domain.c); continue; }
 
 		currcount = CountLabels(&curr->domain);
-		if ((!curr->scoped && (!question->InterfaceID || (question->InterfaceID == mDNSInterface_Unicast))) || (curr->interface == question->InterfaceID))
+		if ((!DEQuery || !curr->cellIntf) &&
+			((!curr->scoped && (!question->InterfaceID || (question->InterfaceID == mDNSInterface_Unicast))) ||
+			(curr->interface == question->InterfaceID)))
 			{
 			bettermatch = BetterMatchForName(&question->qname, namecount, &curr->domain, currcount, bestmatchlen);
 
@@ -7864,6 +7928,7 @@ mDNSexport mDNSu32 SetValidDNSServers(mDNS *m, DNSQuestion *question)
 					" Timeout %d, interface %p", question->qname.c, &curr->addr, curr->domain.c, curr->scoped, index, curr->timeout,
 					curr->interface);
 				timeout += curr->timeout;
+				if (DEQuery) debugf("DomainEnumQuery: Question %##s, DNSServer %#a, cell %d", question->qname.c, &curr->addr, curr->cellIntf);
 				bit_set_opaque64(question->validDNSServers, index);
 				}
 			}
diff --git a/src/tools/mdnssd/mDNSEmbeddedAPI.h b/src/tools/mdnssd/mDNSEmbeddedAPI.h
index 3d6c12a4ec300f5e8d6f0ac1a94c3a702abb8eb6..7310dc56e3d263e04cb7edbec81b7c0c97d50af9 100755
--- a/src/tools/mdnssd/mDNSEmbeddedAPI.h
+++ b/src/tools/mdnssd/mDNSEmbeddedAPI.h
@@ -1075,6 +1075,7 @@ typedef struct DNSServer
 	mDNSBool		scoped;		// interface should be matched against question only
 								// if scoped is set
 	mDNSu32			timeout;	// timeout value for questions
+	mDNSBool        cellIntf;   // Resolver from Cellular Interface ?
 	} DNSServer;
 
 typedef struct							// Size is 36 bytes when compiling for 32-bit; 48 when compiling for 64-bit
@@ -2468,7 +2469,7 @@ extern void RecreateNATMappings(mDNS *const m);
 extern void mDNS_AddDynDNSHostName(mDNS *m, const domainname *fqdn, mDNSRecordCallback *StatusCallback, const void *StatusContext);
 extern void mDNS_RemoveDynDNSHostName(mDNS *m, const domainname *fqdn);
 extern void mDNS_SetPrimaryInterfaceInfo(mDNS *m, const mDNSAddr *v4addr,  const mDNSAddr *v6addr, const mDNSAddr *router);
-extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped, mDNSu32 timeout);
+extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped, mDNSu32 timeout, mDNSBool cellIntf);
 extern void PenalizeDNSServer(mDNS *const m, DNSQuestion *q);
 extern void mDNS_AddSearchDomain(const domainname *const domain, mDNSInterfaceID InterfaceID);
 
@@ -2653,8 +2654,8 @@ extern mDNSBool   mDNSPlatformValidRecordForInterface(AuthRecord *rr, const Netw
 extern void     LNT_SendDiscoveryMsg(mDNS *m);
 extern void     LNT_ConfigureRouterInfo(mDNS *m, const mDNSInterfaceID InterfaceID, const mDNSu8 *const data, const mDNSu16 len);
 extern mStatus  LNT_GetExternalAddress(mDNS *m);
-extern mStatus  LNT_MapPort(mDNS *m, NATTraversalInfo *n);
-extern mStatus  LNT_UnmapPort(mDNS *m, NATTraversalInfo *n);
+extern mStatus  LNT_MapPort(mDNS *m, NATTraversalInfo *const n);
+extern mStatus  LNT_UnmapPort(mDNS *m, NATTraversalInfo *const n);
 extern void     LNT_ClearState(mDNS *const m);
 #endif // _LEGACY_NAT_TRAVERSAL_
 
@@ -2729,6 +2730,7 @@ extern void DNSServerChangeForQuestion(mDNS *const m, DNSQuestion *q, DNSServer
 extern void ActivateUnicastRegistration(mDNS *const m, AuthRecord *const rr);
 extern void CheckSuppressUnusableQuestions(mDNS *const m);
 extern void RetrySearchDomainQuestions(mDNS *const m);
+extern mDNSBool DomainEnumQuery(const domainname *qname);
 
 // Used only in logging to restrict the number of /etc/hosts entries printed
 extern void FreeEtcHosts(mDNS *const m, AuthRecord *const rr, mStatus result);
@@ -2943,7 +2945,7 @@ struct CompileTimeAssertionChecks_mDNS
 	char sizecheck_ZoneData            [(sizeof(ZoneData)             <=  1624) ? 1 : -1];
 	char sizecheck_NATTraversalInfo    [(sizeof(NATTraversalInfo)     <=   192) ? 1 : -1];
 	char sizecheck_HostnameInfo        [(sizeof(HostnameInfo)         <=  3050) ? 1 : -1];
-	char sizecheck_DNSServer           [(sizeof(DNSServer)            <=   320) ? 1 : -1];
+	char sizecheck_DNSServer           [(sizeof(DNSServer)            <=   328) ? 1 : -1];
 	char sizecheck_NetworkInterfaceInfo[(sizeof(NetworkInterfaceInfo) <=  6850) ? 1 : -1];
 	char sizecheck_ServiceRecordSet    [(sizeof(ServiceRecordSet)     <=  5500) ? 1 : -1];
 	char sizecheck_DomainAuthInfo      [(sizeof(DomainAuthInfo)       <=  7808) ? 1 : -1];
diff --git a/src/tools/mdnssd/mDNSPosix.c b/src/tools/mdnssd/mDNSPosix.c
index e56ad9118965e446cb9faabe436a39172b0149c3..a1868709dbe3e146da696d0f42beebffa3f4a226 100755
--- a/src/tools/mdnssd/mDNSPosix.c
+++ b/src/tools/mdnssd/mDNSPosix.c
@@ -27,6 +27,7 @@
  * understand why variable y is not of type "char*" just proves the point that poor code
  * layout leads people to unfortunate misunderstandings about how the C language really works.)
  */
+
 #include "mDNSEmbeddedAPI.h"           // Defines the interface provided to the client layer above
 #include "DNSCommon.h"
 #include "mDNSPosix.h"				 // Defines the specific types needed to run mDNS on this platform
@@ -158,8 +159,12 @@ mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const ms
 	assert(msg != NULL);
 	assert(end != NULL);
 	assert((((char *) end) - ((char *) msg)) > 0);
-	assert(dstPort.NotAnInteger != 0);
 
+	if (dstPort.NotAnInteger == 0) 
+		{
+		LogMsg("mDNSPlatformSendUDP: Invalid argument -dstPort is set to 0");
+		return PosixErrorToStatus(EINVAL);
+		}
 	if (dst->type == mDNSAddrType_IPv4)
 		{
 		struct sockaddr_in *sin = (struct sockaddr_in*)&to;
@@ -501,7 +506,7 @@ mDNSexport int ParseDNSServers(mDNS *m, const char *filePath)
 			mDNSAddr DNSAddr;
 			DNSAddr.type = mDNSAddrType_IPv4;
 			DNSAddr.ip.v4.NotAnInteger = ina.s_addr;
-			mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, &DNSAddr, UnicastDNSPort, mDNSfalse, 0);
+			mDNS_AddDNSServer(m, NULL, mDNSInterface_Any, &DNSAddr, UnicastDNSPort, mDNSfalse, 0, mDNSfalse);
 			numOfServers++;
 			}
 		}  
@@ -710,16 +715,10 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
 		{
 		struct ipv6_mreq imr6;
 		struct sockaddr_in6 bindAddr6;
-	#if defined(IPV6_RECVPKTINFO)
-		if (err == 0)
-		    {
-		    err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_RECVPKTINFO, &kOn, sizeof(kOn));
-		    if (err < 0) { err = errno; perror("setsockopt - IPV6_RECVPKTINFO"); }
-		    }
-	#elif defined(IPV6_PKTINFO)
+#if defined(IPV6_PKTINFO)
 		if (err == 0)
 			{
-				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_PKTINFO, &kOn, sizeof(kOn));
+				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_PKTINFO, &kOn, sizeof(kOn));
 				if (err < 0) { err = errno; perror("setsockopt - IPV6_PKTINFO"); }
 			}
 	#else
@@ -728,7 +727,7 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
 	#if defined(IPV6_HOPLIMIT)
 		if (err == 0)
 			{
-				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_HOPLIMIT, &kOn, sizeof(kOn));
+				err = setsockopt(*sktPtr, IPPROTO_IPV6, IPV6_2292_HOPLIMIT, &kOn, sizeof(kOn));
 				if (err < 0) { err = errno; perror("setsockopt - IPV6_HOPLIMIT"); }
 			}
 	#endif
@@ -846,6 +845,7 @@ mDNSlocal int SetupOneInterface(mDNS *const m, struct sockaddr *intfAddr, struct
 		// Set up the fields required by the mDNS core.
 		SockAddrTomDNSAddr(intfAddr, &intf->coreIntf.ip, NULL);
 		SockAddrTomDNSAddr(intfMask, &intf->coreIntf.mask, NULL);
+
 		//LogMsg("SetupOneInterface: %#a %#a",  &intf->coreIntf.ip,  &intf->coreIntf.mask);
 		strncpy(intf->coreIntf.ifname, intfName, sizeof(intf->coreIntf.ifname));
 		intf->coreIntf.ifname[sizeof(intf->coreIntf.ifname)-1] = 0;
diff --git a/src/tools/mdnssd/mDNSUNP.c b/src/tools/mdnssd/mDNSUNP.c
index e6835cd49b0d9ca0e57030dac285cbc9dd19b347..8027676cfe3bafc7d58bc271f03846533a77210b 100755
--- a/src/tools/mdnssd/mDNSUNP.c
+++ b/src/tools/mdnssd/mDNSUNP.c
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #include "mDNSUNP.h"
 
 #include <errno.h>
@@ -81,7 +82,7 @@ void plen_to_mask(int plen, char *addr) {
 /* Gets IPv6 interface information from the /proc filesystem in linux*/
 struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 	{
-	struct ifi_info *ifi, *ifihead, **ifipnext;
+		struct ifi_info *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
 	FILE *fp;
 	char addr[8][5];
 	int flags, myflags, index, plen, scope;
@@ -91,6 +92,8 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 	struct sockaddr_in6 *sin6;
 	struct in6_addr *addrptr;
 	int err;
+	int sockfd = -1;
+	struct ifreq ifr;
 
 	res0=NULL;
 	ifihead = NULL;
@@ -98,6 +101,10 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 	lastname[0] = 0;
 
 	if ((fp = fopen(PROC_IFINET6_PATH, "r")) != NULL) {
+		sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
+		if (sockfd < 0) {
+			goto gotError;
+		}
 		while (fscanf(fp,
 					  "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
 					  addr[0],addr[1],addr[2],addr[3],
@@ -114,8 +121,10 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 			ifi = (struct ifi_info*)calloc(1, sizeof(struct ifi_info));
 			if (ifi == NULL) {
 				goto gotError;
-				}
-
+			}
+			
+			ifipold   = *ifipnext;       /* need this later */
+			ifiptr    = ifipnext;
 			*ifipnext = ifi;            /* prev points to this new one */
 			ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */
 
@@ -160,9 +169,25 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 			/* Add interface index */
 			ifi->ifi_index = index;
 
-			/* If interface is in /proc then it is up*/
-			ifi->ifi_flags = IFF_UP;
-
+			/* Add interface flags*/
+			memcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+			if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) {
+				if (errno == EADDRNOTAVAIL) {
+					/* 
+					 * If the main interface is configured with no IP address but 
+					 * an alias interface exists with an IP address, you get 
+					 * EADDRNOTAVAIL for the main interface 
+					 */
+					free(ifi->ifi_addr);
+					free(ifi);
+					ifipnext  = ifiptr; 
+					*ifipnext = ifipold;
+					continue;
+				} else {
+					goto gotError;
+				}
+			}
+			ifi->ifi_flags = ifr.ifr_flags;
 			freeaddrinfo(res0);
 			res0=NULL;
 			}
@@ -179,6 +204,9 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 		res0=NULL;
 		}
 	done:
+	if (sockfd != -1) {
+		assert(close(sockfd) == 0);
+	}
 	return(ifihead);    /* pointer to first structure in linked list */
 	}
 #endif // defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
@@ -186,7 +214,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
 struct ifi_info *get_ifi_info(int family, int doaliases)
 {
     int                 junk;
-    struct ifi_info     *ifi, *ifihead, **ifipnext;
+    struct ifi_info     *ifi, *ifihead, **ifipnext, *ifipold, **ifiptr;
     int                 sockfd, sockf6, len, lastlen, flags, myflags;
 #ifdef NOT_HAVE_IF_NAMETOINDEX
     int                 index = 200;
@@ -278,9 +306,11 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
         if (ifi == NULL) {
             goto gotError;
         }
-        *ifipnext = ifi;            /* prev points to this new one */
-        ifipnext = &ifi->ifi_next;  /* pointer to next one goes here */
-
+		ifipold   = *ifipnext;       /* need this later */
+		ifiptr    = ifipnext;
+		*ifipnext = ifi;             /* prev points to this new one */
+		ifipnext  = &ifi->ifi_next;  /* pointer to next one goes here */
+		
         ifi->ifi_flags = flags;     /* IFF_xxx values */
         ifi->ifi_myflags = myflags; /* IFI_xxx values */
 #ifndef NOT_HAVE_IF_NAMETOINDEX
@@ -309,7 +339,23 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
                 memcpy(ifi->ifi_addr, sinptr, sizeof(struct sockaddr_in));
 
 #ifdef  SIOCGIFNETMASK
-				if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) goto gotError;
+				if (ioctl(sockfd, SIOCGIFNETMASK, &ifrcopy) < 0) {
+					if (errno == EADDRNOTAVAIL) {
+						/* 
+						 * If the main interface is configured with no IP address but 
+						 * an alias interface exists with an IP address, you get 
+						 * EADDRNOTAVAIL for the main interface 
+						 */
+						free(ifi->ifi_addr);
+						free(ifi);
+						ifipnext  = ifiptr; 
+						*ifipnext = ifipold;
+						continue;
+					} else {
+						goto gotError;
+					}				
+				}
+
 				ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in));
 				if (ifi->ifi_netmask == NULL) goto gotError;
 				sinptr = (struct sockaddr_in *) &ifrcopy.ifr_addr;
@@ -384,7 +430,22 @@ struct ifi_info *get_ifi_info(int family, int doaliases)
 				memset(&ifr6, 0, sizeof(ifr6));
 				memcpy(&ifr6.ifr_name,           &ifr->ifr_name, sizeof(ifr6.ifr_name          ));
 				memcpy(&ifr6.ifr_ifru.ifru_addr, &ifr->ifr_addr, sizeof(ifr6.ifr_ifru.ifru_addr));
-				if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) goto gotError;
+				if (ioctl(sockf6, SIOCGIFNETMASK_IN6, &ifr6) < 0) {
+					if (errno == EADDRNOTAVAIL) {
+						/* 
+						 * If the main interface is configured with no IP address but 
+						 * an alias interface exists with an IP address, you get 
+						 * EADDRNOTAVAIL for the main interface 
+						 */
+						free(ifi->ifi_addr);
+						free(ifi);
+						ifipnext  = ifiptr; 
+						*ifipnext = ifipold;
+						continue;
+					} else {
+						goto gotError;
+					}				
+				}
 				ifi->ifi_netmask = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in6));
 				if (ifi->ifi_netmask == NULL) goto gotError;
 				sinptr6 = (struct sockaddr_in6 *) &ifr6.ifr_ifru.ifru_addr;
@@ -575,9 +636,9 @@ struct in_pktinfo
         }
 #endif
 
-#if defined(IPV6_PKTINFO) && HAVE_IPV6
-        if (cmptr->cmsg_level == IPPROTO_IPV6 && 
-            cmptr->cmsg_type == IPV6_PKTINFO) {
+#if defined(IPV6_PKTINFO) && HAVE_IPV6 
+		if (cmptr->cmsg_level == IPPROTO_IPV6 && 
+            cmptr->cmsg_type  == IPV6_2292_PKTINFO) {
             struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)&pktp->ipi_addr;
 			struct in6_pktinfo *ip6_info = (struct in6_pktinfo*)CMSG_DATA(cmptr);
 			
@@ -596,7 +657,7 @@ struct in_pktinfo
 
 #if defined(IPV6_HOPLIMIT) && HAVE_IPV6
         if (cmptr->cmsg_level == IPPROTO_IPV6 && 
-            cmptr->cmsg_type == IPV6_HOPLIMIT) {
+            cmptr->cmsg_type == IPV6_2292_HOPLIMIT) {
 			*ttl = *(int*)CMSG_DATA(cmptr);
             continue;
         }
diff --git a/src/tools/mdnssd/mDNSUNP.h b/src/tools/mdnssd/mDNSUNP.h
index 59b5501b37bf5c58a42879893a8f275f3eb94753..6b04601f5095287e926f656e4b5200887e10614f 100755
--- a/src/tools/mdnssd/mDNSUNP.h
+++ b/src/tools/mdnssd/mDNSUNP.h
@@ -25,6 +25,15 @@
 
 #ifdef HAVE_LINUX
 #include <linux/socket.h>
+#define IPV6_2292_PKTINFO  IPV6_2292PKTINFO
+#define IPV6_2292_HOPLIMIT IPV6_2292HOPLIMIT
+#else
+// The following are the supported non-linux posix OSes -
+// netbsd, freebsd and openbsd.
+#if HAVE_IPV6
+#define IPV6_2292_PKTINFO  19
+#define IPV6_2292_HOPLIMIT 20
+#endif 
 #endif
 
 #ifdef  __cplusplus
diff --git a/src/tools/mdnssd/main.cpp b/src/tools/mdnssd/main.cpp
deleted file mode 100644
index 40ce0a533e71c2280cff08a5a4eca23bf482ef29..0000000000000000000000000000000000000000
--- a/src/tools/mdnssd/main.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <QtCore/QCoreApplication>
-
-int main(int argc, char *argv[])
-{
-    QCoreApplication a(argc, argv);
-    
-    return a.exec();
-}
diff --git a/src/tools/mdnssd/mdnssd.pro b/src/tools/mdnssd/mdnssd.pro
index 3eac277fd422719d5e6bfc3efdfbe9f20a31b495..2272a5bf6174a0bde0e31cbe01c39cb7fba33e15 100644
--- a/src/tools/mdnssd/mdnssd.pro
+++ b/src/tools/mdnssd/mdnssd.pro
@@ -51,7 +51,7 @@ HEADERS += \
     QMAKE_CXXFLAGS += -Wno-unused-but-set-variable
 }
 linux-* {
-DEFINES += NOT_HAVE_SA_LEN USES_NETLINK HAVE_LINUX TARGET_OS_LINUX
+DEFINES += _GNU_SOURCE HAVE_IPV6 NOT_HAVE_SA_LEN USES_NETLINK HAVE_LINUX TARGET_OS_LINUX
 }
 macx {
 DEFINES += HAVE_IPV6 __MAC_OS_X_VERSION_MIN_REQUIRED=__MAC_OS_X_VERSION_10_4 __APPLE_USE_RFC_2292
diff --git a/src/tools/mdnssd/uDNS.c b/src/tools/mdnssd/uDNS.c
index 513150bef08ad8fa6d513b2e7e46cedc31639665..57cfc1a689e65361c568fd2c88a5e792ea92f469 100755
--- a/src/tools/mdnssd/uDNS.c
+++ b/src/tools/mdnssd/uDNS.c
@@ -101,7 +101,7 @@ mDNSlocal void SetRecordRetry(mDNS *const m, AuthRecord *rr, mDNSu32 random)
 #pragma mark - Name Server List Management
 #endif
 
-mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped, mDNSu32 timeout)
+mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port, mDNSBool scoped, mDNSu32 timeout, mDNSBool cellIntf)
 	{
 	DNSServer **p = &m->DNSServers;
 	DNSServer *tmp = mDNSNULL;
@@ -150,6 +150,7 @@ mDNSexport DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, cons
 			(*p)->teststate = /* DNSServer_Untested */ DNSServer_Passed;
 			(*p)->lasttest  = m->timenow - INIT_UCAST_POLL_INTERVAL;
 			(*p)->timeout   = timeout;
+			(*p)->cellIntf  = cellIntf;
 			AssignDomainName(&(*p)->domain, d);
 			(*p)->next = mDNSNULL;
 			}
@@ -4108,56 +4109,6 @@ mDNSexport mStatus uDNS_UpdateRecord(mDNS *m, AuthRecord *rr)
 #pragma mark - Periodic Execution Routines
 #endif
 
-mDNSlocal const mDNSu8 *mDNS_WABLabels[] =
-	{
-	(const mDNSu8 *)"\001b",
-	(const mDNSu8 *)"\002db",
-	(const mDNSu8 *)"\002lb",
-	(const mDNSu8 *)"\001r",
-	(const mDNSu8 *)"\002dr",
-	(const mDNSu8 *)mDNSNULL,
-	};
-
-// Returns true if it is a WAB question
-mDNSlocal mDNSBool WABQuestion(const domainname *qname)
-	{
- 	const mDNSu8 *sd = (const mDNSu8 *)"\007_dns-sd";
-	const mDNSu8 *prot = (const mDNSu8 *)"\004_udp";
-	const domainname *d = qname;
-	const mDNSu8 *label;
-	int i = 0;
-
-	// We need at least 3 labels (WAB prefix) + one more label to make
-	// a meaningful WAB query
-	if (CountLabels(qname) < 4) { debugf("WABQuestion: question %##s, not enough labels", qname->c); return mDNSfalse; }
-
-	label = (const mDNSu8 *)d;
-	while (mDNS_WABLabels[i] != (const mDNSu8 *)mDNSNULL)
-		{
-		if (SameDomainLabel(mDNS_WABLabels[i], label)) {debugf("WABquestion: WAB question %##s, label1 match", qname->c); break;}
-		i++;
-		}
-	if (mDNS_WABLabels[i] == (const mDNSu8 *)mDNSNULL)
-		{
-		debugf("WABquestion: Not a WAB question %##s, label1 mismatch", qname->c);
-		return mDNSfalse;
-		}
-	// CountLabels already verified the number of labels 
-	d = (const domainname *)(d->c + 1 + d->c[0]);	// Second Label
-	label = (const mDNSu8 *)d;
-	if (!SameDomainLabel(label, sd)){ debugf("WABquestion: Not a WAB question %##s, label2 mismatch", qname->c);return(mDNSfalse); }
-	debugf("WABquestion: WAB question %##s, label2 match", qname->c);
-
-	d = (const domainname *)(d->c + 1 + d->c[0]); 	// Third Label
-	label = (const mDNSu8 *)d;
-	if (!SameDomainLabel(label, prot)){ debugf("WABquestion: Not a WAB question %##s, label3 mismatch", qname->c);return(mDNSfalse); }
-	debugf("WABquestion: WAB question %##s, label3 match", qname->c);
-
-	LogInfo("WABquestion: Question %##s is a WAB question", qname->c);
-
-	return mDNStrue;
-	}
-
 // The question to be checked is not passed in as an explicit parameter;
 // instead it is implicit that the question to be checked is m->CurrentQuestion.
 mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
@@ -4285,7 +4236,14 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
 						q->ThisQInterval = LLQ_POLL_INTERVAL;
 					LogInfo("uDNS_CheckCurrentQuestion: private non polling question for %##s (%s) will be retried in %d ms", q->qname.c, DNSTypeName(q->qtype), q->ThisQInterval);
 					}
-				debugf("Increased ThisQInterval to %d for %##s (%s)", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype));
+				if (q->qDNSServer->cellIntf)
+					{
+					// We don't want to retransmit too soon. Schedule our first retransmisson at
+					// MIN_UCAST_RETRANS_TIMEOUT seconds.
+					if (q->ThisQInterval < MIN_UCAST_RETRANS_TIMEOUT)
+						q->ThisQInterval = MIN_UCAST_RETRANS_TIMEOUT;
+					}
+				debugf("uDNS_CheckCurrentQuestion: Increased ThisQInterval to %d for %##s (%s), cell %d", q->ThisQInterval, q->qname.c, DNSTypeName(q->qtype), q->qDNSServer->cellIntf);
 				}
 			q->LastQTime = m->timenow;
 			SetNextQueryTime(m, q);
@@ -4351,7 +4309,7 @@ mDNSexport void uDNS_CheckCurrentQuestion(mDNS *const m)
 			// For some of the WAB queries that we generate form within the mDNSResponder, most of the home routers
 			// don't understand and return ServFail/NXDomain. In those cases, we don't want to try too often. We try
 			// every fifteen minutes in that case
-			MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, (WABQuestion(&q->qname) ? 60 * 15 : 60), mDNSInterface_Any, q->qDNSServer);
+			MakeNegativeCacheRecord(m, &m->rec.r, &q->qname, q->qnamehash, q->qtype, q->qclass, (DomainEnumQuery(&q->qname) ? 60 * 15 : 60), mDNSInterface_Any, q->qDNSServer);
 			q->unansweredQueries = 0;
 			// We're already using the m->CurrentQuestion pointer, so CacheRecordAdd can't use it to walk the question list.
 			// To solve this problem we set rr->DelayDelivery to a nonzero value (which happens to be 'now') so that we
diff --git a/src/tools/mdnssd/uDNS.h b/src/tools/mdnssd/uDNS.h
index 2dfaf51ec8c99208b0db823a97a8b0c3fd562d33..8e46ffa77d4e7ec3fe8c86fa01d8a4104c1f1a48 100755
--- a/src/tools/mdnssd/uDNS.h
+++ b/src/tools/mdnssd/uDNS.h
@@ -35,6 +35,10 @@
 #define MAX_UCAST_UNANSWERED_QUERIES 2                       // the number of unanswered queries from any one uDNS server before trying another server
 #define DNSSERVER_PENALTY_TIME (60 * mDNSPlatformOneSecond) // number of seconds for which new questions don't pick this server
 
+// On some interfaces, we want to delay the first retransmission to a minimum of 2 seconds
+// rather than the default (1 second).
+#define MIN_UCAST_RETRANS_TIMEOUT (2 * mDNSPlatformOneSecond)
+
 #define DEFAULT_UPDATE_LEASE 7200
 
 #define QuestionIntervalStep 3