(void)context; // Unused
(void)flags; // Unused
- if (num_printed++ == 0) printf("Timestamp if %-20s %-15s %-15s %-15s %s\n", "External Address", "Protocol", "Internal Port", "External Port", "TTL");
+ if (num_printed++ == 0) printf("Timestamp if %-20s %-15s %-15s %-15s %-6s\n", "External Address", "Protocol", "Internal Port", "External Port", "TTL");
printtimestamp();
- if (errorCode) printf("Error code %d\n", errorCode);
+ if (errorCode && errorCode != kDNSServiceErr_DoubleNAT) printf("Error code %d\n", errorCode);
else
{
const unsigned char *digits = (const unsigned char *)&publicAddress;
char addr[256];
snprintf(addr, sizeof(addr), "%d.%d.%d.%d", digits[0], digits[1], digits[2], digits[3]);
- printf("%-4d %-20s %-15d %-15d %-15d %d\n", ifIndex, addr, protocol, ntohs(privatePort), ntohs(publicPort), ttl);
+ printf("%-4d %-20s %-15d %-15d %-15d %-6d%s\n", ifIndex, addr, protocol, ntohs(privatePort), ntohs(publicPort), ttl, errorCode == kDNSServiceErr_DoubleNAT ? " Double NAT" : "");
}
fflush(stdout);
}
(void) sdref;
(void) context;
- if (num_printed++ == 0) printf("Timestamp A/R Flags if %-25s %-40s %s\n", "Hostname", "Address", "TTL");
+ if (num_printed++ == 0) printf("Timestamp A/R Flags if %-25s %-44s %s\n", "Hostname", "Address", "TTL");
printtimestamp();
if (address && address->sa_family == AF_INET)
{
- const unsigned char *digits = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr;
- snprintf(addr, sizeof(addr), "%d.%d.%d.%d", digits[0], digits[1], digits[2], digits[3]);
+ const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr;
+ snprintf(addr, sizeof(addr), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]);
}
else if (address && address->sa_family == AF_INET6)
{
- const unsigned char *digits = (const unsigned char *) &((struct sockaddr_in6 *)address)->sin6_addr;
- snprintf(addr, sizeof(addr), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X",
- digits[0x0], digits[0x1], digits[0x2], digits[0x3], digits[0x4], digits[0x5], digits[0x6], digits[0x7],
- digits[0x8], digits[0x9], digits[0xA], digits[0xB], digits[0xC], digits[0xD], digits[0xE], digits[0xF]);
+ char if_name[IFNAMSIZ]; // Older Linux distributions don't define IF_NAMESIZE
+ const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *)address;
+ const unsigned char *b = (const unsigned char * )&s6->sin6_addr;
+ if (!if_indextoname(s6->sin6_scope_id, if_name))
+ snprintf(if_name, sizeof(if_name), "<%d>", s6->sin6_scope_id);
+ snprintf(addr, sizeof(addr), "%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%%%s",
+ b[0x0], b[0x1], b[0x2], b[0x3], b[0x4], b[0x5], b[0x6], b[0x7],
+ b[0x8], b[0x9], b[0xA], b[0xB], b[0xC], b[0xD], b[0xE], b[0xF], if_name);
}
- printf("%s%6X%3d %-25s %-40s %d", op, flags, interfaceIndex, hostname, addr, ttl);
+ printf("%s%6X%3d %-25s %-44s %d", op, flags, interfaceIndex, hostname, addr, ttl);
if (errorCode)
{
if (errorCode == kDNSServiceErr_NoSuchRecord) printf(" No Such Record");
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-170"
+MVERS = "mDNSResponder-171.4"
DDNSWRITECONFIG = "$(DSTROOT)/Library/Application Support/Bonjour/ddnswriteconfig"
Change History (most recent first):
$Log: DNSCommon.c,v $
+Revision 1.199 2008/03/14 19:58:38 mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.198 2008/03/07 23:29:24 cheshire
+Fixed cosmetic byte order display issue in DumpPacket output
+
+Revision 1.197 2008/03/05 22:51:29 mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Even further refinements
+
+Revision 1.196 2008/03/05 22:01:53 cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Now that we optionally add the HINFO record, when rewriting the header fields into network byte
+order, we need to use our updated msg->h.numAdditionals, not the stack variable numAdditionals
+
+Revision 1.195 2008/03/05 19:06:30 mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+further refinements
+
+Revision 1.194 2008/03/05 00:26:06 cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+
Revision 1.193 2007/12/17 23:42:36 cheshire
Added comments about DNSDigest_SignMessage()
rd->soa.serial, rd->soa.refresh, rd->soa.retry, rd->soa.expire, rd->soa.min);
break;
- case kDNSType_HINFO:// Display this the same as TXT (show all constituent string)
+ case kDNSType_HINFO:// Display this the same as TXT (show all constituent strings)
case kDNSType_TXT: {
mDNSu8 *t = rd->txt.c;
while (t < rd->txt.c + rr->rdlength)
return end;
}
+mDNSexport mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end, DomainAuthInfo *authInfo)
+ {
+ if (authInfo && authInfo->AutoTunnel)
+ {
+ AuthRecord hinfo;
+ mDNSu8 *h = hinfo.rdatastorage.u.data;
+ mDNSu16 len = 2 + m->HIHardware.c[0] + m->HISoftware.c[0];
+ mDNSu8 *newptr;
+ mDNS_SetupResourceRecord(&hinfo, mDNSNULL, mDNSInterface_Any, kDNSType_HINFO, 0, kDNSRecordTypeUnique, mDNSNULL, mDNSNULL);
+ AppendDomainLabel(&hinfo.namestorage, &m->hostlabel);
+ AppendDomainName (&hinfo.namestorage, &authInfo->domain);
+ hinfo.resrec.rroriginalttl = 0;
+ mDNSPlatformMemCopy(h, &m->HIHardware, 1 + (mDNSu32)m->HIHardware.c[0]);
+ h += 1 + (int)h[0];
+ mDNSPlatformMemCopy(h, &m->HISoftware, 1 + (mDNSu32)m->HISoftware.c[0]);
+ hinfo.resrec.rdlength = len;
+ hinfo.resrec.rdestimate = len;
+ newptr = PutResourceRecord(msg, end, &msg->h.numAdditionals, &hinfo.resrec);
+ return newptr;
+ }
+ else
+ return end;
+ }
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
mDNSInterfaceID InterfaceID, const mDNSAddr *dst, mDNSIPPort dstport, TCPSocket *sock, DomainAuthInfo *authInfo)
{
mStatus status = mStatus_NoError;
- mDNSu16 numQuestions = msg->h.numQuestions;
- mDNSu16 numAnswers = msg->h.numAnswers;
- mDNSu16 numAuthorities = msg->h.numAuthorities;
- mDNSu16 numAdditionals = msg->h.numAdditionals;
+ const mDNSu16 numQuestions = msg->h.numQuestions;
+ const mDNSu16 numAnswers = msg->h.numAnswers;
+ const mDNSu16 numAuthorities = msg->h.numAuthorities;
+ const mDNSu16 numAdditionals = msg->h.numAdditionals;
+ mDNSu16 tmpNumAdditionals = numAdditionals;
mDNSu8 *ptr = (mDNSu8 *)&msg->h.numQuestions;
if (end <= msg->data || end - msg->data > AbsoluteMaxDNSMessageData)
return mStatus_BadParamErr;
}
- // Put all the integer values in IETF byte-order (MSB first, LSB second)
- *ptr++ = (mDNSu8)(numQuestions >> 8);
- *ptr++ = (mDNSu8)(numQuestions & 0xFF);
- *ptr++ = (mDNSu8)(numAnswers >> 8);
- *ptr++ = (mDNSu8)(numAnswers & 0xFF);
- *ptr++ = (mDNSu8)(numAuthorities >> 8);
- *ptr++ = (mDNSu8)(numAuthorities & 0xFF);
- *ptr++ = (mDNSu8)(numAdditionals >> 8);
- *ptr++ = (mDNSu8)(numAdditionals & 0xFF);
-
- if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0); // DNSDigest_SignMessage operates on message in network byte order
- if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
+ end = putHINFO(m, msg, end, authInfo);
+ if (!end) { LogMsg("mDNSSendDNSMessage: putHINFO failed"); status = mStatus_NoMemoryErr; }
else
{
- // Send the packet on the wire
- if (!sock)
- status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, dst, dstport);
+ tmpNumAdditionals = msg->h.numAdditionals;
+
+ // Put all the integer values in IETF byte-order (MSB first, LSB second)
+ *ptr++ = (mDNSu8)(numQuestions >> 8);
+ *ptr++ = (mDNSu8)(numQuestions & 0xFF);
+ *ptr++ = (mDNSu8)(numAnswers >> 8);
+ *ptr++ = (mDNSu8)(numAnswers & 0xFF);
+ *ptr++ = (mDNSu8)(numAuthorities >> 8);
+ *ptr++ = (mDNSu8)(numAuthorities & 0xFF);
+ *ptr++ = (mDNSu8)(tmpNumAdditionals >> 8);
+ *ptr++ = (mDNSu8)(tmpNumAdditionals & 0xFF);
+
+ if (authInfo) DNSDigest_SignMessage(msg, &end, authInfo, 0); // DNSDigest_SignMessage operates on message in network byte order
+ if (!end) { LogMsg("mDNSSendDNSMessage: DNSDigest_SignMessage failed"); status = mStatus_NoMemoryErr; }
else
{
- mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
- mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
- long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2); // Should do scatter/gather here -- this is probably going out as two packets
- if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
+ // Send the packet on the wire
+ if (!sock)
+ status = mDNSPlatformSendUDP(m, msg, end, InterfaceID, dst, dstport);
else
{
- nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
- if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
+ mDNSu16 msglen = (mDNSu16)(end - (mDNSu8 *)msg);
+ mDNSu8 lenbuf[2] = { (mDNSu8)(msglen >> 8), (mDNSu8)(msglen & 0xFF) };
+ long nsent = mDNSPlatformWriteTCP(sock, (char*)lenbuf, 2); // Should do scatter/gather here -- this is probably going out as two packets
+ if (nsent != 2) { LogMsg("mDNSSendDNSMessage: write msg length failed %d/%d", nsent, 2); status = mStatus_ConnFailed; }
+ else
+ {
+ nsent = mDNSPlatformWriteTCP(sock, (char *)msg, msglen);
+ if (nsent != msglen) { LogMsg("mDNSSendDNSMessage: write msg body failed %d/%d", nsent, msglen); status = mStatus_ConnFailed; }
+ }
}
}
}
msg->h.numQuestions = numQuestions;
msg->h.numAnswers = numAnswers;
msg->h.numAuthorities = numAuthorities;
- msg->h.numAdditionals = numAdditionals;
+ // Dump the packet with the HINFO and TSIG
if (mDNS_LogLevel >= MDNS_LOG_VERBOSE_DEBUG && !mDNSOpaque16IsZero(msg->h.id))
{
- if (authInfo) msg->h.numAdditionals++; // Want to include TSIG in DumpPacket output
+ ptr = (mDNSu8 *)&msg->h.numAdditionals;
+ msg->h.numAdditionals = (mDNSu16)ptr[0] << 8 | (mDNSu16)ptr[1];
DumpPacket(m, mDNStrue, sock && (sock->flags & kTCPSocketFlags_UseTLS) ? "TLS" : sock ? "TCP" : "UDP", dst, dstport, msg, end);
- if (authInfo) msg->h.numAdditionals--;
}
+ // put the final integer value back the way it was
+ msg->h.numAdditionals = numAdditionals;
+
return(status);
}
Change History (most recent first):
$Log: DNSCommon.h,v $
+Revision 1.59 2008/03/14 19:58:38 mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.58 2008/03/06 21:26:10 cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
Revision 1.57 2007/12/13 20:20:17 cheshire
Minor efficiency tweaks -- converted IdenticalResourceRecord, IdenticalSameNameRecord, and
SameRData from functions to macros, which allows the code to be inlined (the compiler can't
extern "C" {
#endif
+//*************************************************************************************************************
+// Macros
+
+// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
+// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
+// To expand "version" to its value before making the string, use STRINGIFY(version) instead
+#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
+#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - DNS Protocol Constants
extern mDNSu8 *putUpdateLease(DNSMessage *msg, mDNSu8 *end, mDNSu32 lease);
#define PutResourceRecord(MSG, P, C, RR) PutResourceRecordTTL((MSG), (P), (C), (RR), (RR)->rroriginalttl)
+extern mDNSu8 *putHINFO(const mDNS *const m, DNSMessage *const msg, mDNSu8 *end, DomainAuthInfo *authInfo);
+
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark -
Change History (most recent first):
$Log: mDNS.c,v $
+Revision 1.776 2008/04/17 20:14:14 cheshire
+<rdar://problem/5870023> CurrentAnswers/LargeAnswers/UniqueAnswers counter mismatch
+
+Revision 1.775 2008/03/26 01:53:34 mcguire
+<rdar://problem/5820489> Can't resolve via uDNS when an interface is specified
+
+Revision 1.774 2008/03/17 17:46:08 mcguire
+When activating an LLQ, reset all the important state and destroy any tcp connection,
+so that everything will be restarted as if the question had just been asked.
+Also reset servPort, so that the SOA query will be re-issued.
+
+Revision 1.773 2008/03/14 22:52:36 mcguire
+<rdar://problem/5321824> write status to the DS
+Update status when any unicast LLQ is started
+
+Revision 1.772 2008/03/06 02:48:34 mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.771 2008/02/26 22:04:44 cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+Additional fixes -- should not be calling uDNS_CheckCurrentQuestion on a
+question while it's still in our 'm->NewQuestions' section of the list
+
+Revision 1.770 2008/02/22 23:09:02 cheshire
+<rdar://problem/5338420> BTMM: Not processing additional records
+Refinements:
+1. Check rdatahash == namehash, to skip expensive SameDomainName check when possible
+2. Once we decide a record is acceptable, we can break out of the loop
+
+Revision 1.769 2008/02/22 00:00:19 cheshire
+<rdar://problem/5338420> BTMM: Not processing additional records
+
+Revision 1.768 2008/02/19 23:26:50 cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+
Revision 1.767 2007/12/22 02:25:29 cheshire
<rdar://problem/5661128> Records and Services sometimes not re-registering on wake from sleep
if (m->CurrentQuestion)
LogMsg("SendQueries ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
m->CurrentQuestion = m->Questions;
- while (m->CurrentQuestion)
+ while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
{
q = m->CurrentQuestion;
if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID)) uDNS_CheckCurrentQuestion(m);
// m->CurrentQuestion point to the right question
if (q == m->CurrentQuestion) m->CurrentQuestion = m->CurrentQuestion->next;
}
+ m->CurrentQuestion = mDNSNULL;
// Scan our list of questions
// (a) to see if there are any more that are worth accelerating, and
// which causes NextScheduledQuery to get (incorrectly) set to m->timenow. Setting it here is the right place, because the very
// next thing we do is scan the list and call SetNextQueryTime() for every question we find, so we know we end up with the right value.
m->NextScheduledQuery = m->timenow + 0x78000000;
- for (q = m->Questions; q; q=q->next)
+ for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
{
if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow ||
(!q->Target.type && ActiveQuestion(q) && q->ThisQInterval <= maxExistingQuestionInterval && AccelerateThisQuery(m,q))))
mDNSu32 answerforecast = 0;
// Put query questions in this packet
- for (q = m->Questions; q; q=q->next)
+ for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
{
if (mDNSOpaque16IsZero(q->TargetQID) && (q->SendQNow == intf->InterfaceID))
{
q->RecentAnswerPkts = 0;
q->ThisQInterval = MaxQuestionInterval;
q->RequestUnicast = mDNSfalse;
+ debugf("AnswerCurrentQuestionWithResourceRecord: Set MaxQuestionInterval for %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
}
if (rr->DelayDelivery) return; // We'll come back later when CacheRecordDeferredAdd() calls us
mDNSlocal void CacheRecordAdd(mDNS *const m, CacheRecord *rr)
{
DNSQuestion *q;
- for (q = m->Questions; q; q=q->next)
+
+ // We stop when we get to NewQuestions -- if we increment their CurrentAnswers/LargeAnswers/UniqueAnswers
+ // counters here we'll end up double-incrementing them when we do it again in AnswerNewQuestion().
+ for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
{
if (ResourceRecordAnswersQuestion(&rr->resrec, q))
{
if (m->CurrentQuestion)
LogMsg("NoCacheAnswer ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
m->CurrentQuestion = m->Questions;
+ // We do this for *all* questions, not stopping when we get to m->NewQuestions,
+ // since we're not caching the record and we'll get no opportunity to do this later
while (m->CurrentQuestion)
{
DNSQuestion *q = m->CurrentQuestion;
m->CurrentQuestion = mDNSNULL;
}
-// CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute
+// CacheRecordRmv is only called from CheckCacheExpiration, which is called from mDNS_Execute.
+// Note that CacheRecordRmv is *only* called for records that are referenced by at least one active question.
// If new questions are created as a result of invoking client callbacks, they will be added to
// the end of the question list, and m->NewQuestions will be set to indicate the first new question.
// rr is an existing cache CacheRecord that just expired and is being deleted
if (m->CurrentQuestion)
LogMsg("CacheRecordRmv ERROR m->CurrentQuestion already set: %##s (%s)", m->CurrentQuestion->qname.c, DNSTypeName(m->CurrentQuestion->qtype));
m->CurrentQuestion = m->Questions;
+
+ // We stop when we get to NewQuestions -- for new questions their CurrentAnswers/LargeAnswers/UniqueAnswers counters
+ // will all still be zero because we haven't yet gone through the cache counting how many answers we have for them.
while (m->CurrentQuestion && m->CurrentQuestion != m->NewQuestions)
{
DNSQuestion *q = m->CurrentQuestion;
m->CurrentRecord = mDNSNULL;
}
+ if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving LocalOnly record answers");
+
if (m->CurrentQuestion == q)
{
CacheRecord *rr;
ShouldQueryImmediately = mDNSfalse;
}
+ if (m->CurrentQuestion != q) debugf("AnswerNewQuestion: question deleted while giving cache answers");
+
if (m->CurrentQuestion == q && ShouldQueryImmediately && ActiveQuestion(q))
{
+ debugf("AnswerNewQuestion: ShouldQueryImmediately %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
q->ThisQInterval = InitialQuestionInterval;
q->LastQTime = m->timenow - q->ThisQInterval;
- if (mDNSOpaque16IsZero(q->TargetQID))
+ if (mDNSOpaque16IsZero(q->TargetQID)) // For mDNS, spread packets to avoid a burst of simultaneous queries
{
// Compute random delay in the range 1-6 seconds, then divide by 50 to get 20-120ms
if (!m->RandomQueryDelay)
m->RandomQueryDelay = (mDNSPlatformOneSecond + mDNSRandom(mDNSPlatformOneSecond*5) - 1) / 50 + 1;
q->LastQTime += m->RandomQueryDelay;
}
-
- m->NextScheduledQuery = m->timenow;
+
+ if (m->NextScheduledQuery - (q->LastQTime + q->ThisQInterval) > 0)
+ m->NextScheduledQuery = (q->LastQTime + q->ThisQInterval);
}
m->CurrentQuestion = mDNSNULL;
mDNSlocal void AnswerNewLocalOnlyQuestion(mDNS *const m)
{
DNSQuestion *q = m->NewLocalOnlyQuestions; // Grab the question we're going to answer
- m->NewLocalOnlyQuestions = q->next; // Advance NewQuestions to the next (if any)
+ m->NewLocalOnlyQuestions = q->next; // Advance NewLocalOnlyQuestions to the next (if any)
debugf("AnswerNewLocalOnlyQuestion: Answering %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
LogMsg("mDNS_Execute: SendQueries didn't send all its queries (%d - %d = %d) will try again in one second",
m->timenow, m->NextScheduledQuery, m->timenow - m->NextScheduledQuery);
m->NextScheduledQuery = m->timenow + mDNSPlatformOneSecond;
- for (q = m->Questions; q; q=q->next)
+ for (q = m->Questions; q && q != m->NewQuestions; q=q->next)
if (ActiveQuestion(q) && q->LastQTime + q->ThisQInterval - m->timenow <= 0)
LogMsg("mDNS_Execute: SendQueries didn't send %##s (%s)", q->qname.c, DNSTypeName(q->qtype));
}
{ q->ReqLease = 0; sendLLQRefresh(m, q); }
}
-mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question)
+// ActivateUnicastQuery() is called from three places:
+// 1. When a new question is created
+// 2. On wake from sleep
+// 3. When the DNS configuration changes
+// In case 1 we don't want to mess with our established ThisQInterval and LastQTime (ScheduleImmediately is false)
+// In cases 2 and 3 we do want to cause the question to be resent immediately (ScheduleImmediately is true)
+mDNSlocal void ActivateUnicastQuery(mDNS *const m, DNSQuestion *const question, mDNSBool ScheduleImmediately)
{
// For now this AutoTunnel stuff is specific to Mac OS X.
// In the future, if there's demand, we may see if we can abstract it out cleanly into the platform layer
if (!question->DuplicateOf)
{
- LogOperation("ActivateUnicastQuery: %##s %s%s",
- question->qname.c, DNSTypeName(question->qtype), question->AuthInfo ? " (Private)" : "");
+ LogOperation("ActivateUnicastQuery: %##s %s%s%s",
+ question->qname.c, DNSTypeName(question->qtype), question->AuthInfo ? " (Private)" : "", ScheduleImmediately ? " ScheduleImmediately" : "");
if (question->nta) { CancelGetZoneData(m, question->nta); question->nta = mDNSNULL; }
- if (question->LongLived) { question->state = LLQ_InitialRequest; question->id = zeroOpaque64; }
- question->ThisQInterval = InitialQuestionInterval;
- question->LastQTime = m->timenow - question->ThisQInterval;
- SetNextQueryTime(m, question);
+ if (question->LongLived)
+ {
+ question->state = LLQ_InitialRequest;
+ question->id = zeroOpaque64;
+ question->servPort = zeroIPPort;
+ if (question->tcp) { DisposeTCPConn(question->tcp); question->tcp = mDNSNULL; }
+ }
+ if (ScheduleImmediately)
+ {
+ question->ThisQInterval = InitialQuestionInterval;
+ question->LastQTime = m->timenow - question->ThisQInterval;
+ SetNextQueryTime(m, question);
+ }
}
}
{
q = m->CurrentQuestion;
m->CurrentQuestion = m->CurrentQuestion->next;
- if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q);
+ if (!mDNSOpaque16IsZero(q->TargetQID)) ActivateUnicastQuery(m, q, mDNStrue);
}
// and reactivtate service registrations
m->NextSRVUpdate = NonZeroTime(m->timenow + mDNSPlatformOneSecond);
default: RDLength = m->rec.r.resrec.rdlength; break;
}
+ if (!m->rec.r.resrec.InterfaceID) debugf("CreateNewCacheEntry %s", CRDisplayString(m, &m->rec.r));
+
//if (RDLength > InlineCacheRDSize)
// LogOperation("Rdata len %4d > InlineCacheRDSize %d %s", RDLength, InlineCacheRDSize, CRDisplayString(m, &m->rec.r));
// All records in a DNS response packet are treated as equally valid statements of truth. If we want
// to guard against spoof responses, then the only credible protection against that is cryptographic
// security, e.g. DNSSEC., not worring about which section in the spoof packet contained the record
- int totalrecords = response->h.numAnswers + response->h.numAuthorities + response->h.numAdditionals;
+ int firstauthority = response->h.numAnswers;
+ int firstadditional = firstauthority + response->h.numAuthorities;
+ int totalrecords = firstadditional + response->h.numAdditionals;
const mDNSu8 *ptr = response->data;
// Currently used only for display in debugging message
// (Note that just because we are willing to cache something, that doesn't necessarily make it a trustworthy answer
// to any specific question -- any code reading records from the cache needs to make that determination for itself.)
- const mDNSu8 RecordType = (mDNSu8)((i < response->h.numAnswers) ? kDNSRecordTypePacketAns : kDNSRecordTypePacketAdd);
+ const mDNSu8 RecordType =
+ (i < firstauthority ) ? (mDNSu8)kDNSRecordTypePacketAns :
+ (i < firstadditional) ? (mDNSu8)kDNSRecordTypePacketAuth : (mDNSu8)kDNSRecordTypePacketAdd;
ptr = GetLargeResourceRecord(m, response, ptr, end, InterfaceID, RecordType, &m->rec);
if (!ptr) goto exit; // Break out of the loop and clean up our CacheFlushRecords list before exiting
+
// Don't want to cache OPT or TSIG pseudo-RRs
if (m->rec.r.resrec.rrtype == kDNSType_OPT || m->rec.r.resrec.rrtype == kDNSType_TSIG)
{ m->rec.r.resrec.RecordType = 0; continue; }
}
}
+ if (!AcceptableResponse)
+ {
+ CacheRecord *cr;
+ for (cr = CacheFlushRecords; cr != (CacheRecord*)1; cr = cr->NextInCFList)
+ {
+ domainname *target = GetRRDomainNameTarget(&cr->resrec);
+ if (target && cr->resrec.rdatahash == m->rec.r.resrec.namehash && SameDomainName(target, m->rec.r.resrec.name))
+ { AcceptableResponse = mDNStrue; break; }
+ }
+ }
+
// 2. See if we want to add this packet resource record to our cache
// We only try to cache answers if we have a cache to put them in
// Also, we ignore any apparent attempts at cache poisoning unicast to us that do not answer any outstanding active query
+ if (!AcceptableResponse) debugf("mDNSCoreReceiveResponse ignoring %s", CRDisplayString(m, &m->rec.r));
if (m->rrcache_size && AcceptableResponse)
{
const mDNSu32 slot = HashSlot(m->rec.r.resrec.name);
for (q = m->Questions; q; q=q->next)
if (ActiveQuestion(q) && !mDNSOpaque16IsZero(q->TargetQID) && q->LongLived)
startLLQHandshake(m, q); // If ExternalPort is zero, will do StartLLQPolling instead
+#if APPLE_OSX_mDNSResponder
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
mDNS_Unlock(m);
}
question->TargetQID = zeroID;
}
+ question->TargetQID =
#ifndef UNICAST_DISABLED
- // If the client has specified 'kDNSServiceFlagsForceMulticast'
- // then we do a multicast query on that interface, even for unicast domains.
- if (question->InterfaceID == mDNSInterface_LocalOnly || question->ForceMCast || IsLocalDomain(&question->qname))
- question->TargetQID = zeroID;
- else
- question->TargetQID = mDNS_NewMessageID(m);
-#else
- question->TargetQID = zeroID;
+ (question->InterfaceID != mDNSInterface_LocalOnly && !question->ForceMCast && !IsLocalDomain(&question->qname)) ? mDNS_NewMessageID(m) :
#endif // UNICAST_DISABLED
+ zeroID;
debugf("mDNS_StartQuery: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
for (i=0; i<DupSuppressInfoSize; i++)
question->DupSuppress[i].InterfaceID = mDNSNULL;
- if (!question->DuplicateOf)
- debugf("mDNS_StartQuery: Question %##s (%s) %p %d (%p) started",
- question->qname.c, DNSTypeName(question->qtype), question->InterfaceID,
- question->LastQTime + question->ThisQInterval - m->timenow, question);
- else
- debugf("mDNS_StartQuery: Question %##s (%s) %p %d (%p) duplicate of (%p)",
- question->qname.c, DNSTypeName(question->qtype), question->InterfaceID,
- question->LastQTime + question->ThisQInterval - m->timenow, question, question->DuplicateOf);
+ debugf("mDNS_StartQuery: Question %##s (%s) Interface %p Now %d Send in %d Answer in %d (%p) %s (%p)",
+ question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, m->timenow,
+ question->LastQTime + question->ThisQInterval - m->timenow,
+ question->DelayAnswering ? question->DelayAnswering - m->timenow : 0,
+ question, question->DuplicateOf ? "duplicate of" : "not duplicate", question->DuplicateOf);
if (question->InterfaceID == mDNSInterface_LocalOnly)
{
if (!mDNSOpaque16IsZero(question->TargetQID))
{
question->qDNSServer = GetServerForName(m, &question->qname);
- ActivateUnicastQuery(m, question);
+ ActivateUnicastQuery(m, question, mDNSfalse);
// If long-lived query, and we don't have our NAT mapping active, start it now
if (question->LongLived && !m->LLQNAT.clientContext)
m->LLQNAT.clientContext = (void*)1; // Means LLQ NAT Traversal is active
mDNS_StartNATOperation_internal(m, &m->LLQNAT);
}
+
+#if APPLE_OSX_mDNSResponder
+ if (question->LongLived)
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
+
}
SetNextQueryTime(m,question);
}
question->tcp = mDNSNULL;
}
}
+#if APPLE_OSX_mDNSResponder
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
}
return(mStatus_NoError);
s, s ? &s->addr : mDNSNULL, mDNSVal16(s ? s->port : zeroIPPort), s ? s->domain.c : (mDNSu8*)"",
q->qname.c, DNSTypeName(q->qtype));
q->qDNSServer = s;
- ActivateUnicastQuery(m, q);
+ ActivateUnicastQuery(m, q, mDNStrue);
}
}
Change History (most recent first):
$Log: mDNSDebug.h,v $
+Revision 1.39 2008/02/26 21:17:11 cheshire
+Grouped all user settings together near the start of the file; added LogTimeStamps option
+
Revision 1.38 2007/12/13 20:27:07 cheshire
Remove unused VerifySameNameAssumptions symbol
// warning: repeated `#' flag in format (for %##s -- DNS name string format)
// warning: double format, pointer arg (arg 2) (for %.4a, %.16a, %#a -- IP address formats)
#define MDNS_CHECK_PRINTF_STYLE_FUNCTIONS 0
+
+typedef enum
+ {
+ MDNS_LOG_NONE,
+// MDNS_LOG_ERROR,
+// MDNS_LOG_WARN,
+// MDNS_LOG_INFO,
+// MDNS_LOG_DEBUG,
+ MDNS_LOG_VERBOSE_DEBUG
+ } LogLevel_t;
+
+#define MDNS_LOG_INITIAL_LEVEL MDNS_LOG_NONE
+
+// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
+#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
+
+// Set this symbol to 1 to do extra debug checks on malloc() and free()
+// Set this symbol to 2 to write a log message for every malloc() and free()
+#define MACOSX_MDNS_MALLOC_DEBUGGING 0
+
+#define LogAllOperations 0
+#define LogTimeStamps 0
+#define ForceAlerts 0
+
+// Developer-settings section ends here
+
#if MDNS_CHECK_PRINTF_STYLE_FUNCTIONS
#define IS_A_PRINTF_STYLE_FUNCTION(F,A) __attribute__ ((format(printf,F,A)))
#else
#endif
// LogMsg is used even in shipping code, to write truly serious error messages to syslog (or equivalent)
-typedef enum
- {
- MDNS_LOG_NONE,
-// MDNS_LOG_ERROR,
-// MDNS_LOG_WARN,
-// MDNS_LOG_INFO,
-// MDNS_LOG_DEBUG,
- MDNS_LOG_VERBOSE_DEBUG
- } LogLevel_t;
-
-#define MDNS_LOG_INITIAL_LEVEL MDNS_LOG_NONE
-
extern LogLevel_t mDNS_LogLevel;
extern int mDNS_DebugMode; // If non-zero, LogMsg() writes to stderr instead of syslog
extern const char ProgramName[]; // Program Name for use with LogMsgIdent
extern void LogMsgNoIdent(const char *format, ...) IS_A_PRINTF_STYLE_FUNCTION(1,2);
extern void SigLogLevel(void);
-// Set this symbol to 1 to answer remote queries for our Address, reverse mapping PTR, and HINFO records
-#define ANSWER_REMOTE_HOSTNAME_QUERIES 0
-
-// Set this symbol to 1 to do extra debug checks on malloc() and free()
-// Set this symbol to 2 to write a log message for every malloc() and free()
-#define MACOSX_MDNS_MALLOC_DEBUGGING 0
-
#if APPLE_OSX_mDNSResponder && MACOSX_MDNS_MALLOC_DEBUGGING >= 1
extern void *mallocL(char *msg, unsigned int size);
extern void freeL(char *msg, void *x);
#define freeL(X,Y) free(Y)
#endif
-#define LogAllOperations 0
-
#if LogAllOperations
#define LogOperation LogMsg
#else
#define LogOperation debugf
#endif
-#define ForceAlerts 0
-
#ifdef __cplusplus
}
#endif
Change History (most recent first):
$Log: mDNSEmbeddedAPI.h,v $
+Revision 1.468 2008/03/06 02:48:34 mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.467 2008/02/26 20:48:46 cheshire
+Need parentheses around use of macro argument in mDNS_TimeNow_NoLock(m)
+
+Revision 1.466 2008/02/21 21:36:32 cheshire
+Updated comment about record type values (kDNSRecordTypePacketAns/Auth/Add)
+
+Revision 1.465 2008/02/20 00:39:05 mcguire
+<rdar://problem/5427102> Some device info XML blobs too large
+
+Revision 1.464 2008/01/31 23:33:29 mcguire
+<rdar://problem/5614450> changes to build using gcc 4.2 with -Werror
+
Revision 1.463 2007/12/17 23:53:25 cheshire
Added DNSDigest_SignMessageHostByteOrder, for signing messages not yet converted to network byte order
mStatus_BadKey = -65561,
mStatus_TransientErr = -65562, // transient failures, e.g. sending packets shortly after a network transition or wake from sleep
mStatus_ServiceNotRunning = -65563, // Background daemon not running
- mStatus_NATPortMappingUnsupported = -65564, // No NAT or if the NAT doesn't support NAT-PMP or UPnP
+ mStatus_NATPortMappingUnsupported = -65564, // NAT doesn't support NAT-PMP or UPnP
mStatus_NATPortMappingDisabled = -65565, // NAT supports NAT-PMP or UPnP but it's disabled by the administrator
- // -65566 to -65786 currently unused; available for allocation
+ mStatus_NoRouter = -65566,
+ mStatus_PollingMode = -65567,
+ // -65568 to -65786 currently unused; available for allocation
// tcp connection status
mStatus_ConnPending = -65787,
// Cache Resource Records (received from the network):
// There are four basic types: Answer, Unique Answer, Additional, Unique Additional
// Bit 7 (the top bit) of kDNSRecordType is always set for Cache Resource Records; always clear for Authoritative Resource Records
-// Bit 6 (value 0x40) is set for answer records; clear for additional records
+// Bit 6 (value 0x40) is set for answer records; clear for authority/additional records
// Bit 5 (value 0x20) is set for records received with the kDNSClass_UniqueRRSet
enum
LNTPortMapDeleteOp = 4
} LNTOp_t;
-#define LNT_MAXBUFSIZE 4096
+#define LNT_MAXBUFSIZE 8192
typedef struct tcpLNTInfo_struct tcpLNTInfo;
struct tcpLNTInfo_struct
{
extern DNSServer *mDNS_AddDNSServer(mDNS *const m, const domainname *d, const mDNSInterfaceID interface, const mDNSAddr *addr, const mDNSIPPort port);
extern void mDNS_AddSearchDomain(const domainname *const domain);
+// We use ((void *)0) here instead of mDNSNULL to avoid compile warnings on gcc 4.2
#define mDNS_AddSearchDomain_CString(X) \
- do { domainname d__; if ((X) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__); } while(0)
+ do { domainname d__; if (((X) != (void*)0) && MakeDomainNameFromDNSNameString(&d__, (X)) && d__.c[0]) mDNS_AddSearchDomain(&d__); } while(0)
// Routines called by the core, exported by DNSDigest.c
extern mStatus mDNSPlatformTimeInit (void);
extern mDNSs32 mDNSPlatformRawTime (void);
extern mDNSs32 mDNSPlatformUTC (void);
-#define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + m->timenow_adjust)
+#define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + (m)->timenow_adjust)
#if MDNS_DEBUGMSGS
extern void mDNSPlatformWriteDebugMsg(const char *msg);
extern void AutoTunnelCallback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord);
extern void AddNewClientTunnel(mDNS *const m, DNSQuestion *const q);
extern void SetupLocalAutoTunnelInterface_internal(mDNS *const m);
+extern void UpdateAutoTunnelDomainStatuses(const mDNS *const m);
#endif
// ***************************************************************************
Change History (most recent first):
$Log: uDNS.c,v $
+Revision 1.553.2.1 2008/03/14 20:11:25 mcguire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+Make sure we add the record when sending LLQ refreshes
+
+Revision 1.553 2008/03/06 02:48:34 mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.552 2008/03/05 01:56:42 cheshire
+<rdar://problem/5687667> BTMM: Don't fallback to unencrypted operations when SRV lookup fails
+
+Revision 1.551 2008/03/01 01:43:04 cheshire
+<rdar://problem/5631565> BTMM: Lots of "Error getting external address 3" when double-NATed prevents sleep
+Added code to suppress logging of multiple identical error results
+
+Revision 1.550 2008/03/01 01:34:47 cheshire
+<rdar://problem/5736313> BTMM: Double-NAT'd machines register all but AutoTunnel v4 address records
+Further refinements
+
+Revision 1.549 2008/02/29 01:35:37 mcguire
+<rdar://problem/5736313> BTMM: Double-NAT'd machines register all but AutoTunnel v4 address records
+
+Revision 1.548 2008/02/20 23:54:18 cheshire
+<rdar://problem/5661518> "Failed to obtain NAT port mapping" syslog messages
+Improved log message so it tells us more about what's going on
+
+Revision 1.547 2008/02/20 00:41:09 cheshire
+Change "PrivateQueryGotZoneData ... invoked with error code" from LogMsg to LogOperation
+
+Revision 1.546 2008/02/19 23:26:50 cheshire
+<rdar://problem/5661661> BTMM: Too many members.mac.com SOA queries
+
Revision 1.545 2007/12/22 02:25:29 cheshire
<rdar://problem/5661128> Records and Services sometimes not re-registering on wake from sleep
mDNSexport void natTraversalHandleAddressReply(mDNS *const m, mDNSu16 err, mDNSv4Addr ExtAddr)
{
- if (err) LogMsg("Error getting external address %d", err);
+ static mDNSu16 last_err;
+ if (err)
+ {
+ if (err != last_err) LogMsg("Error getting external address %d", err);
+ }
else if (!mDNSSameIPv4Address(m->ExternalAddress, ExtAddr))
{
LogOperation("Received external IP address %.4a from NAT", &ExtAddr);
m->retryGetAddr = m->timenow + m->retryIntervalGetAddr;
if (m->NextScheduledNATOp - m->retryIntervalGetAddr > 0)
m->NextScheduledNATOp = m->retryIntervalGetAddr;
+
+ last_err = err;
}
// Both places that call NATSetNextRenewalTime() update m->NextScheduledNATOp correctly afterwards
// we risk causing spurious "SendQueries didn't send all its queries" log messages
q->LastQTime = m->timenow - q->ThisQInterval + 1;
SetNextQueryTime(m, q);
+#if APPLE_OSX_mDNSResponder
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
}
mDNSlocal mDNSu8 *putLLQ(DNSMessage *const msg, mDNSu8 *ptr, const DNSQuestion *const question, const LLQOptData *const data, mDNSBool includeQuestion)
q->state = LLQ_Established;
q->ntries = 0;
SetLLQTimer(m, q, llq);
+#if APPLE_OSX_mDNSResponder
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
}
}
{
debugf("GetZoneData GOT SRV %s", RRDisplayString(m, answer));
mDNS_StopQuery(m, question);
+// Right now we don't want to fail back to non-encrypted operations
+// If the AuthInfo has the AutoTunnel field set, then we want private or nothing
+// <rdar://problem/5687667> BTMM: Don't fallback to unencrypted operations when SRV lookup fails
+#if 0
if (!answer->rdlength && zd->ZonePrivate && zd->ZoneService != ZoneServiceQuery)
{
zd->ZonePrivate = mDNSfalse; // Causes ZoneDataSRV() to yield a different SRV name when building the query
GetZoneData_StartQuery(m, zd, kDNSType_SRV); // Try again, non-private this time
}
else
+#endif
{
if (answer->rdlength)
{
zd->Host.c[0] = 0;
zd->Port = zeroIPPort;
zd->Addr = zeroAddr;
- zd->ZonePrivate = AuthInfo ? mDNStrue : mDNSfalse;
+ zd->ZonePrivate = AuthInfo && AuthInfo->AutoTunnel ? mDNStrue : mDNSfalse;
zd->ZoneDataCallback = callback;
zd->ZoneDataContext = ZoneDataContext;
UpdateSRVRecords(m);
GetStaticHostname(m); // look up reverse map record to find any static hostnames for our IP address
+#if APPLE_OSX_mDNSResponder
+ UpdateAutoTunnelDomainStatuses(m);
+#endif
}
mDNS_Unlock(m);
"\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\xa" "dnsbugtest"
"\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\x7" "in-addr" "\x4" "arpa";
+// See comments above for DNSRelayTestQuestion
+// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
+mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
+ {
+ int i;
+ mDNSu8 *p = q->qname.c;
+ if (q->AuthInfo) return(mDNStrue); // Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
+ if (q->qtype != kDNSType_PTR) return(mDNStrue); // Don't need a test query for any non-PTR queries
+ for (i=0; i<4; i++) // If qname does not begin with num.num.num.num, can't skip the test query
+ {
+ if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
+ if ( p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
+ if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
+ if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
+ p += 1 + p[0];
+ }
+ // If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
+ // we can safely do it without needing a test query first, otherwise we need the test query.
+ return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
+ }
+
// Returns mDNStrue if response was handled
mDNSlocal mDNSBool uDNS_ReceiveTestQuestionResponse(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport)
if (mDNSSameAddress(srcaddr, &s->addr) && mDNSSameIPPort(srcport, s->port) && s->teststate != result)
{
DNSQuestion *q;
- if (s->teststate != result)
- {
- s->teststate = result;
- if (result == DNSServer_Passed) LogOperation("DNS Server %#a:%d passed", srcaddr, mDNSVal16(srcport));
- else LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d", srcaddr, mDNSVal16(srcport));
- }
+ s->teststate = result;
+ if (result == DNSServer_Passed) LogOperation("DNS Server %#a:%d passed", srcaddr, mDNSVal16(srcport));
+ else LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a:%d", srcaddr, mDNSVal16(srcport));
+
+ // If this server has just changed state from DNSServer_Untested to DNSServer_Passed, then retrigger any waiting questions.
+ // We use the NoTestQuery() test so that we only retrigger questions that were actually blocked waiting for this test to complete.
if (result == DNSServer_Passed) // Unblock any questions that were waiting for this result
for (q = m->Questions; q; q=q->next)
- if (q->qDNSServer == s)
+ if (q->qDNSServer == s && !NoTestQuery(q))
{ q->LastQTime = m->timenow - q->ThisQInterval; m->NextScheduledQuery = m->timenow; }
}
InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
end = putLLQ(&m->omsg, m->omsg.data, q, &llq, mDNStrue);
if (!end) { LogMsg("sendLLQRefresh: putLLQ failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
+
+ // Note that we (conditionally) add HINFO and TSIG here, since the question might be going away,
+ // so we may not be able to reference it (most importantly it's AuthInfo) when we actually send the message
+ end = putHINFO(m, &m->omsg, end, q->AuthInfo);
+ if (!end) { LogMsg("sendLLQRefresh: putHINFO failed %##s (%s)", q->qname.c, DNSTypeName(q->qtype)); return; }
+
if (q->AuthInfo)
{
DNSDigest_SignMessageHostByteOrder(&m->omsg, &end, q->AuthInfo);
// we use for cleaning up if our LLQ is cancelled *before* the GetZoneData operation has completes).
q->nta = mDNSNULL;
- if (err)
+ if (err || !zoneInfo || mDNSAddressIsZero(&zoneInfo->Addr) || mDNSIPPortIsZero(zoneInfo->Port))
{
- LogMsg("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %ld", q->qname.c, DNSTypeName(q->qtype), err);
+ LogOperation("ERROR: PrivateQueryGotZoneData %##s (%s) invoked with error code %ld %p %#a:%d",
+ q->qname.c, DNSTypeName(q->qtype), err, zoneInfo,
+ zoneInfo ? &zoneInfo->Addr : mDNSNULL,
+ zoneInfo ? mDNSVal16(zoneInfo->Port) : 0);
return;
}
#pragma mark - Periodic Execution Routines
#endif
-// See comments above for DNSRelayTestQuestion
-// If this is the kind of query that has the risk of crashing buggy DNS servers, we do a test question first
-mDNSlocal mDNSBool NoTestQuery(DNSQuestion *q)
- {
- int i;
- mDNSu8 *p = q->qname.c;
- if (q->AuthInfo) return(mDNStrue); // Don't need a test query for private queries sent directly to authoritative server over TLS/TCP
- if (q->qtype != kDNSType_PTR) return(mDNStrue); // Don't need a test query for any non-PTR queries
- for (i=0; i<4; i++) // If qname does not begin with num.num.num.num, can't skip the test query
- {
- if (p[0] < 1 || p[0] > 3) return(mDNSfalse);
- if ( p[1] < '0' || p[1] > '9' ) return(mDNSfalse);
- if (p[0] >= 2 && (p[2] < '0' || p[2] > '9')) return(mDNSfalse);
- if (p[0] >= 3 && (p[3] < '0' || p[3] > '9')) return(mDNSfalse);
- p += 1 + p[0];
- }
- // If remainder of qname is ".in-addr.arpa.", this is a vanilla reverse-mapping query and
- // we can safely do it without needing a test query first, otherwise we need the test query.
- return(SameDomainName((domainname*)p, (const domainname*)"\x7" "in-addr" "\x4" "arpa"));
- }
-
// 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)
{
mDNSu8 *end = m->omsg.data;
mStatus err = mStatus_NoError;
- DomainAuthInfo *private = mDNSNULL;
+ mDNSBool private = mDNSfalse;
if (q->qDNSServer->teststate != DNSServer_Untested || NoTestQuery(q))
{
InitializeDNSMessage(&m->omsg.h, q->TargetQID, uQueryFlags);
end = putQuestion(&m->omsg, m->omsg.data, m->omsg.data + AbsoluteMaxDNSMessageData, &q->qname, q->qtype, q->qclass);
- private = q->AuthInfo;
+ private = (q->AuthInfo && q->AuthInfo->AutoTunnel);
}
else if (m->timenow - q->qDNSServer->lasttest >= INIT_UCAST_POLL_INTERVAL) // Make sure at least three seconds has elapsed since last test query
{
// and (3) we have new data to give the client that's changed since the last callback
if (!mDNSIPv4AddressIsZero(m->ExternalAddress) || m->retryIntervalGetAddr > NATMAP_INIT_RETRY * 8)
{
+ const mStatus EffectiveResult = cur->NewResult ? cur->NewResult : mDNSv4AddrIsRFC1918(&m->ExternalAddress) ? mStatus_DoubleNAT : mStatus_NoError;
const mDNSIPPort ExternalPort = HaveRoutable ? cur->IntPort :
!mDNSIPv4AddressIsZero(m->ExternalAddress) && cur->ExpiryTime ? cur->RequestedPort : zeroIPPort;
if (!cur->Protocol || HaveRoutable || cur->ExpiryTime || cur->retryInterval > NATMAP_INIT_RETRY * 8)
if (!mDNSSameIPv4Address(cur->ExternalAddress, m->ExternalAddress) ||
!mDNSSameIPPort (cur->ExternalPort, ExternalPort) ||
- cur->Result != cur->NewResult)
+ cur->Result != EffectiveResult)
{
//LogMsg("NAT callback %d %d %d", cur->Protocol, cur->ExpiryTime, cur->retryInterval);
if (cur->Protocol && mDNSIPPortIsZero(ExternalPort) && !mDNSIPv4AddressIsZero(m->Router.ip.v4))
- LogMsg("Failed to obtain NAT port mapping from router %#a external address %.4a internal port %d",
- &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort));
+ LogMsg("Failed to obtain NAT port mapping %p from router %#a external address %.4a internal port %d error %d",
+ cur, &m->Router, &m->ExternalAddress, mDNSVal16(cur->IntPort), EffectiveResult);
+
cur->ExternalAddress = m->ExternalAddress;
cur->ExternalPort = ExternalPort;
cur->Lifetime = cur->ExpiryTime && !mDNSIPPortIsZero(ExternalPort) ?
(cur->ExpiryTime - m->timenow + mDNSPlatformOneSecond/2) / mDNSPlatformOneSecond : 0;
- cur->Result = cur->NewResult;
+ cur->Result = EffectiveResult;
mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
if (cur->clientCallback)
cur->clientCallback(m, cur);
<string>com.apple.mDNSResponderHelper</string>
<key>OnDemand</key>
<true/>
+ <key>HopefullyExitsLast</key>
+ <true/>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/mDNSResponderHelper</string>
<string>com.apple.mDNSResponder</string>
<key>OnDemand</key>
<false/>
- <key>UserName</key>
- <string>_mdnsresponder</string>
- <key>GroupName</key>
- <string>_mdnsresponder</string>
+ <key>HopefullyExitsFirst</key>
+ <true/>
+ <key>UserName</key>
+ <string>_mdnsresponder</string>
+ <key>GroupName</key>
+ <string>_mdnsresponder</string>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/mDNSResponder</string>
Change History (most recent first):
$Log: daemon.c,v $
+Revision 1.358 2008/03/06 21:26:11 cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
+Revision 1.357 2008/02/13 17:40:43 cheshire
+<rdar://problem/5740501> Investigate mysterious SIGABRTs in mDNSResponder
+
Revision 1.356 2007/12/18 00:28:56 cheshire
<rdar://problem/5526800> BTMM: Need to deregister records and services on shutdown/sleep
Error in ReadyForSleep() logic -- missing "not" in "!mDNSOpaque16IsZero(q->TargetQID)"
#include <DNSServiceDiscovery/DNSServiceDiscovery.h>
#include "helper.h"
-//*************************************************************************************************************
-// Macros
-
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
//*************************************************************************************************************
// Globals
}
}
+mDNSlocal void CatchABRT(int sig)
+ {
+ LogMsg("Received SIGABRT %d", sig);
+ sleep(1); // Pause to make sure syslog gets the message
+ while(1) *(long*)0 = 0; // Generate a CrashReporter stack trace so we can find out what library called abort();
+ }
+
mDNSlocal void INFOCallback(void)
{
mDNSs32 utc = mDNSPlatformUTC();
signal(SIGHUP, HandleSIG); // (Debugging) Purge the cache to check for cache handling bugs
signal(SIGINT, HandleSIG); // Ctrl-C: Detach from Mach BootstrapService and exit cleanly
+ signal(SIGABRT, CatchABRT); // For debugging -- SIGABRT should never happen
signal(SIGPIPE, SIG_IGN ); // Don't want SIGPIPE signals -- we'll handle EPIPE errors directly
signal(SIGTERM, HandleSIG); // Machine shutting down: Detach from and exit cleanly like Ctrl-C
signal(SIGINFO, HandleSIG); // (Debugging) Write state snapshot to syslog
Change History (most recent first):
$Log: helper.c,v $
+Revision 1.24 2008/01/30 19:01:51 mcguire
+<rdar://problem/5703989> Crash in mDNSResponderHelper
+
Revision 1.23 2007/11/30 23:21:51 cheshire
Rename variables to eliminate "declaration of 'sin_loc' shadows a previous local" warning
{
char buf[2048];
va_list ap;
- ssize_t n = snprintf(buf, sizeof(buf), "%s: ", func);
- if (n >= (int)sizeof(buf))
- return;
va_start(ap, fmt);
- vsnprintf(&buf[n], sizeof(buf)-n, fmt, ap);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
- helplog(ASL_LEVEL_DEBUG, buf);
+ helplog(ASL_LEVEL_DEBUG, "%s: %s", func, buf);
}
static int
Change History (most recent first):
$Log: mDNSMacOSX.c,v $
+Revision 1.536 2008/03/25 01:27:30 mcguire
+<rdar://problem/5810718> Status sometimes wrong when link goes down
+
+Revision 1.535 2008/03/14 22:52:51 mcguire
+<rdar://problem/5321824> write status to the DS
+Ignore duplicate queries, which don't get established (since they're duplicates)
+
+Revision 1.534 2008/03/12 22:58:15 mcguire
+<rdar://problem/5321824> write status to the DS
+Fixes for NO_SECURITYFRAMEWORK
+
+Revision 1.533 2008/03/07 00:48:54 mcguire
+<rdar://problem/5321824> write status to the DS
+cleanup strings
+
+Revision 1.532 2008/03/06 23:44:39 mcguire
+<rdar://problem/5321824> write status to the DS
+cleanup function names & log messages
+add external port numbers to dictionary
+add defensive code in case CF*Create fails
+don't output NAT statuses if zero
+
+Revision 1.531 2008/03/06 21:27:47 cheshire
+<rdar://problem/5500969> BTMM: Need ability to identify version of mDNSResponder client
+To save network bandwidth, removed unnecessary redundant information from HINFO record
+
+Revision 1.530 2008/03/06 03:15:48 mcguire
+<rdar://problem/5321824> write status to the DS
+use mStatus_* instead of kDNSServiceErr_*
+
+Revision 1.529 2008/03/06 02:48:35 mcguire
+<rdar://problem/5321824> write status to the DS
+
+Revision 1.528 2008/02/29 01:33:57 mcguire
+<rdar://problem/5611801> BTMM: Services stay registered after previously successful NAT Port mapping fails
+
+Revision 1.527 2008/02/28 03:25:26 mcguire
+<rdar://problem/5535772> config cleanup on shutdown/reboot
+
+Revision 1.526 2008/02/26 21:43:54 cheshire
+Renamed 'clockdivisor' to 'mDNSPlatformClockDivisor' (LogTimeStamps code needs to be able to access it)
+
+Revision 1.525 2008/02/20 00:53:20 cheshire
+<rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+Removed overly alarming syslog message
+
+Revision 1.524 2008/01/31 22:25:10 jgraessley
+<rdar://problem/5715434> using default Macintosh-0016CBF62EFD.local
+Use sysctlbyname to get hardware type for the default name.
+
+Revision 1.523 2008/01/15 01:32:56 jgraessley
+Bug #: 5595309
+Reviewed by: Stuart Cheshire
+Additional change to print warning message up to 1000 times to make it more visible
+
+Revision 1.522 2008/01/15 01:14:02 mcguire
+<rdar://problem/5674390> mDNSPlatformSendUDP should allow unicast queries on specific interfaces
+removed check and log message, as they are no longer relevant
+
Revision 1.521 2007/12/14 00:58:28 cheshire
<rdar://problem/5526800> BTMM: Need to deregister records and services on shutdown/sleep
Additional fixes: When going to sleep, mDNSResponder needs to postpone sleep
#pragma mark - Globals
#endif
-static mDNSu32 clockdivisor = 0;
-
mDNSexport int KQueueFD;
#ifndef NO_SECURITYFRAMEWORK
int s = -1, err;
mStatus result = mStatus_NoError;
- // Sanity check: Make sure that if we're sending a query via unicast, we're sending it using our
- // anonymous socket created for this purpose, so that we'll receive the response.
- // If we use one of the many multicast sockets bound to port 5353 then we may not receive responses reliably.
- if (InterfaceID && !mDNSAddrIsDNSMulticast(dst))
- if ((((DNSMessage *)msg)->h.flags.b[0] & kDNSFlag0_QR_Mask) == kDNSFlag0_QR_Query)
- LogMsg("mDNSPlatformSendUDP: ERROR: Sending query OP from mDNS port to non-mDNS destination %#a:%d", dst, mDNSVal16(dstPort));
-
if (dst->type == mDNSAddrType_IPv4)
{
struct sockaddr_in *sin_to = (struct sockaddr_in*)&to;
#else
{
static int displayed = 0;
- if (!displayed)
+ if (displayed < 1000)
{
- displayed = 1;
+ displayed++;
LogOperation("IP_FORCE_OUT_IFP Socket option not defined -- cannot specify interface for unicast packets");
}
}
static mDNSBool AnonymousRacoonConfig = mDNSfalse;
+#ifndef NO_SECURITYFRAMEWORK
+
+static CFMutableDictionaryRef domainStatusDict = NULL;
+
+// MUST be called with lock held
+mDNSlocal void RemoveAutoTunnelDomainStatus(const DomainAuthInfo *const info)
+ {
+ char buffer[1024];
+ CFStringRef domain;
+
+ LogOperation("RemoveAutoTunnelDomainStatus: %##s", info->domain.c);
+
+ if (!domainStatusDict) { LogMsg("RemoveAutoTunnelDomainStatus: No domainStatusDict"); return; }
+
+ buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c) - 1] = 0;
+ domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!domain) { LogMsg("RemoveAutoTunnelDomainStatus: Could not create CFString domain"); return; }
+
+ if (CFDictionaryContainsKey(domainStatusDict, domain))
+ {
+ CFDictionaryRemoveValue(domainStatusDict, domain);
+ mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+ }
+ CFRelease(domain);
+ }
+
+#endif // ndef NO_SECURITYFRAMEWORK
+
+// MUST be called with lock held
+mDNSlocal void UpdateAutoTunnelDomainStatus(const mDNS *const m, const DomainAuthInfo *const info)
+ {
+#ifdef NO_SECURITYFRAMEWORK
+ (void)m;
+ (void)info;
+#else
+ const NATTraversalInfo *const llq = m->LLQNAT.clientContext ? &m->LLQNAT : mDNSNULL;
+ const NATTraversalInfo *const tun = info->AutoTunnelNAT.clientContext ? &info->AutoTunnelNAT : mDNSNULL;
+ char buffer[1024];
+ CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFStringRef domain = NULL;
+ CFStringRef tmp = NULL;
+ CFNumberRef num = NULL;
+ mStatus status = mStatus_NoError;
+
+ if (!domainStatusDict)
+ {
+ domainStatusDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ if (!domainStatusDict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary domainStatusDict"); return; }
+ }
+
+ if (!dict) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFDictionary dict"); return; }
+
+ buffer[mDNS_snprintf(buffer, sizeof(buffer), "%##s", info->domain.c) - 1] = 0;
+ domain = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!domain) { LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString domain"); return; }
+
+ mDNS_snprintf(buffer, sizeof(buffer), "%#a", &m->Router);
+ tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!tmp)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString RouterAddress");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("RouterAddress"), tmp);
+ CFRelease(tmp);
+ }
+
+ mDNS_snprintf(buffer, sizeof(buffer), "%.4a", &m->ExternalAddress);
+ tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!tmp)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString ExternalAddress");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("ExternalAddress"), tmp);
+ CFRelease(tmp);
+ }
+
+ if (llq)
+ {
+ mDNSu32 port = mDNSVal16(llq->ExternalPort);
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQExternalPort");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("LLQExternalPort"), num);
+ CFRelease(num);
+ }
+
+ if (llq->Result)
+ {
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &llq->Result);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber LLQNPMStatus");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("LLQNPMStatus"), num);
+ CFRelease(num);
+ }
+ }
+ }
+
+ if (tun)
+ {
+ mDNSu32 port = mDNSVal16(tun->ExternalPort);
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &port);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelExternalPort");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("AutoTunnelExternalPort"), num);
+ CFRelease(num);
+ }
+
+ if (tun->Result)
+ {
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &tun->Result);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber AutoTunnelNPMStatus");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("AutoTunnelNPMStatus"), num);
+ CFRelease(num);
+ }
+ }
+ }
+
+ if (!llq && !tun)
+ {
+ status = mStatus_NotInitializedErr;
+ mDNS_snprintf(buffer, sizeof(buffer), "Neither LLQ nor AutoTunnel NAT port mapping is currently active");
+ }
+ else if ((llq && llq->Result == mStatus_DoubleNAT) || (tun && tun->Result == mStatus_DoubleNAT))
+ {
+ status = mStatus_DoubleNAT;
+ mDNS_snprintf(buffer, sizeof(buffer), "Double NAT: Router is reporting an external address");
+ }
+ else if ((llq && llq->Result) || (tun && tun->Result))
+ {
+ status = mStatus_NATTraversal;
+ mDNS_snprintf(buffer, sizeof(buffer), "Error obtaining NAT port mapping from router");
+ }
+ else if (m->Router.type == mDNSAddrType_None)
+ {
+ status = mStatus_NoRouter;
+ mDNS_snprintf(buffer, sizeof(buffer), "No network connection - none");
+ }
+ else if (m->Router.type == mDNSAddrType_IPv4 && mDNSIPv4AddressIsZero(m->Router.ip.v4))
+ {
+ status = mStatus_NoRouter;
+ mDNS_snprintf(buffer, sizeof(buffer), "No network connection - v4 zero");
+ }
+ else if ((llq && mDNSIPPortIsZero(llq->ExternalPort)) || (tun && mDNSIPPortIsZero(tun->ExternalPort)))
+ {
+ status = mStatus_NATTraversal;
+ mDNS_snprintf(buffer, sizeof(buffer), "Unable to obtain NAT port mapping from router");
+ }
+ else
+ {
+ DNSQuestion* q;
+ for (q = m->Questions; q; q=q->next)
+ if (q->LongLived && q->AuthInfo == info && q->state == LLQ_Poll)
+ {
+ status = mStatus_PollingMode;
+ mDNS_snprintf(buffer, sizeof(buffer), "Query polling %##s", q->qname.c);
+ break;
+ }
+ if (status == mStatus_NoError)
+ for (q = m->Questions; q; q=q->next)
+ if (q->LongLived && q->AuthInfo == info && q->state != LLQ_Established && !q->DuplicateOf)
+ {
+ status = mStatus_TransientErr;
+ mDNS_snprintf(buffer, sizeof(buffer), "Query not yet established %##s", q->qname.c);
+ break;
+ }
+ if (status == mStatus_NoError) mDNS_snprintf(buffer, sizeof(buffer), "Success");
+ }
+
+ num = CFNumberCreate(NULL, kCFNumberSInt32Type, &status);
+ if (!num)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFNumber StatusCode");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("StatusCode"), num);
+ CFRelease(num);
+ }
+
+ tmp = CFStringCreateWithCString(NULL, buffer, kCFStringEncodingUTF8);
+ if (!tmp)
+ LogMsg("UpdateAutoTunnelDomainStatus: Could not create CFString StatusMessage");
+ else
+ {
+ CFDictionarySetValue(dict, CFSTR("StatusMessage"), tmp);
+ CFRelease(tmp);
+ }
+
+ if (!CFDictionaryContainsKey(domainStatusDict, domain) ||
+ !CFEqual(dict, (CFMutableDictionaryRef)CFDictionaryGetValue(domainStatusDict, domain)))
+ {
+ CFDictionarySetValue(domainStatusDict, domain, dict);
+ mDNSDynamicStoreSetConfig(kmDNSBackToMyMacConfig, domainStatusDict);
+ }
+
+ CFRelease(domain);
+ CFRelease(dict);
+
+ LogOperation("UpdateAutoTunnelDomainStatus: %s", buffer);
+#endif // def NO_SECURITYFRAMEWORK
+ }
+
+// MUST be called with lock held
+mDNSexport void UpdateAutoTunnelDomainStatuses(const mDNS *const m)
+ {
+#ifdef NO_SECURITYFRAMEWORK
+ (void)m;
+#else
+ DomainAuthInfo* info;
+ for (info = m->AuthInfoList; info; info = info->next)
+ if (info->AutoTunnel && !info->deltime)
+ UpdateAutoTunnelDomainStatus(m, info);
+#endif // def NO_SECURITYFRAMEWORK
+ }
+
// MUST be called with lock held
mDNSlocal mDNSBool TunnelServers(mDNS *const m)
{
if (result == mStatus_MemFree)
{
LogOperation("AutoTunnelRecordCallback MemFree %s", ARDisplayString(m, rr));
+ // Reset the host record namestorage to force high-level PTR/SRV/TXT to deregister
+ if (rr == &info->AutoTunnelHostRecord)
+ {
+ rr->namestorage.c[0] = 0;
+ m->NextSRVUpdate = NonZeroTime(m->timenow);
+ }
RegisterAutoTunnelRecords(m,info);
}
}
// Create or revert configuration file, and start (or SIGHUP) Racoon
(void)mDNSConfigureServer(AnonymousRacoonConfig ? kmDNSUp : kmDNSDown, info ? info->b64keydata : "");
}
+
+ UpdateAutoTunnelDomainStatus(m, (DomainAuthInfo *)n->clientContext);
}
mDNSlocal void AbortDeregistration(mDNS *const m, AuthRecord *rr)
#pragma mark - Power State & Configuration Change Management
#endif
+mDNSlocal void GenerateDefaultName(const mDNSEthAddr PrimaryMAC, char *buffer, mDNSu32 length)
+{
+ char hwName[32];
+ size_t hwNameLen = sizeof(hwName);
+
+ hwName[0] = 0;
+ if (sysctlbyname("hw.model", &hwName, &hwNameLen, NULL, 0) == 0)
+ {
+ // hw.model contains a number like iMac6,1. We want the "iMac" part.
+ hwName[sizeof(hwName) - 1] = 0;
+ char *ptr;
+ for (ptr = hwName; *ptr != 0; ptr++)
+ {
+ if (*ptr >= '0' && *ptr <= '9') *ptr = 0;
+ if (*ptr == ',') break;
+ }
+ // Prototype model names do not contain commas, do not use prototype names
+ if (*ptr != ',') hwName[0] = 0;
+ }
+
+ if (hwName[0] == 0) strlcpy(hwName, "Device", sizeof(hwName));
+
+ mDNS_snprintf(buffer, length, "%s-%02X%02X%02X%02X%02X%02X", hwName,
+ PrimaryMAC.b[0], PrimaryMAC.b[1], PrimaryMAC.b[2], PrimaryMAC.b[3], PrimaryMAC.b[4], PrimaryMAC.b[5]);
+}
+
mDNSlocal mStatus UpdateInterfaceList(mDNS *const m, mDNSs32 utc)
{
mDNSBool foundav4 = mDNSfalse;
struct ifaddrs *v4Loopback = NULL;
struct ifaddrs *v6Loopback = NULL;
mDNSEthAddr PrimaryMAC = zeroEthAddr;
- char defaultname[32];
+ char defaultname[64];
#ifndef NO_IPV6
int InfoSocket = socket(AF_INET6, SOCK_DGRAM, 0);
if (InfoSocket < 3 && errno != EAFNOSUPPORT) LogMsg("UpdateInterfaceList: InfoSocket error %d errno %d (%s)", InfoSocket, errno, strerror(errno));
LogMsg("getifaddrs: ifa_netmask is NULL for %5s(%d) Flags %04X Family %2d %#a",
ifa->ifa_name, if_nametoindex(ifa->ifa_name), ifa->ifa_flags, ifa->ifa_addr->sa_family, &ip);
}
- else if (ifa->ifa_addr->sa_family != ifa->ifa_netmask->sa_family)
+ // Apparently it's normal for the sa_family of an ifa_netmask to sometimes be zero, so we don't complain about that
+ // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+ else if (ifa->ifa_netmask->sa_family != ifa->ifa_addr->sa_family && ifa->ifa_netmask->sa_family != 0)
{
mDNSAddr ip;
SetupAddr(&ip, ifa->ifa_addr);
}
else
{
+ // Make sure ifa_netmask->sa_family is set correctly
+ // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+ ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family;
int ifru_flags6 = 0;
#ifndef NO_IPV6
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
m->AutoTunnelHostAddr.b[0xC], m->AutoTunnelHostAddr.b[0xD], m->AutoTunnelHostAddr.b[0xE], m->AutoTunnelHostAddr.b[0xF]);
LogOperation("m->AutoTunnelLabel %#s", m->AutoTunnelLabel.c);
}
-
- #ifndef kDefaultLocalHostNamePrefix
- #define kDefaultLocalHostNamePrefix "Macintosh"
- #endif
- mDNS_snprintf(defaultname, sizeof(defaultname), kDefaultLocalHostNamePrefix "-%02X%02X%02X%02X%02X%02X",
- PrimaryMAC.b[0], PrimaryMAC.b[1], PrimaryMAC.b[2], PrimaryMAC.b[3], PrimaryMAC.b[4], PrimaryMAC.b[5]);
+
+ GenerateDefaultName(PrimaryMAC, defaultname, sizeof(defaultname));
// Set up the nice label
domainlabel nicelabel;
ifa->ifa_netmask &&
!(ifa->ifa_flags & IFF_LOOPBACK) &&
!SetupAddr(&a, ifa->ifa_addr) &&
- !SetupAddr(&n, ifa->ifa_netmask) &&
!mDNSv4AddressIsLinkLocal(&a.ip.v4) )
{
+ // Apparently it's normal for the sa_family of an ifa_netmask to sometimes be incorrect, so we explicitly fix it here before calling SetupAddr
+ // <rdar://problem/5492035> getifaddrs is returning invalid netmask family for fw0 and vmnet
+ ifa->ifa_netmask->sa_family = ifa->ifa_addr->sa_family; // Make sure ifa_netmask->sa_family is set correctly
+ SetupAddr(&n, ifa->ifa_netmask);
// Note: This is reverse order compared to a normal dotted-decimal IP address, so we can't use our customary "%.4a" format code
mDNS_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa.", a.ip.v4.b[3] & n.ip.v4.b[3],
a.ip.v4.b[2] & n.ip.v4.b[2],
LogOperation("SetDomainSecrets: secret changed for %##s", &domain);
(void)mDNSConfigureServer(kmDNSUp, stringbuf);
}
+
+ if (ptr->AutoTunnel) UpdateAutoTunnelDomainStatus(m, ptr);
#endif APPLE_OSX_mDNSResponder
ConvertDomainNameToCString(&domain, stringbuf);
DomainAuthInfo *info = m->AuthInfoList;
while (info)
{
- if (info->AutoTunnel && info->deltime && info->AutoTunnelNAT.clientContext)
+ if (info->AutoTunnel && info->deltime)
{
- // stop the NAT operation
- mDNS_StopNATOperation_internal(m, &info->AutoTunnelNAT);
- if (info->AutoTunnelNAT.clientCallback)
+ if (info->AutoTunnelNAT.clientContext)
{
- // Reset port and let the AutoTunnelNATCallback handle cleanup
- info->AutoTunnelNAT.ExternalAddress = m->ExternalAddress;
- info->AutoTunnelNAT.ExternalPort = zeroIPPort;
- info->AutoTunnelNAT.Lifetime = 0;
- info->AutoTunnelNAT.Result = mStatus_NoError;
- mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
- info->AutoTunnelNAT.clientCallback(m, &info->AutoTunnelNAT);
- mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
+ // stop the NAT operation
+ mDNS_StopNATOperation_internal(m, &info->AutoTunnelNAT);
+ if (info->AutoTunnelNAT.clientCallback)
+ {
+ // Reset port and let the AutoTunnelNATCallback handle cleanup
+ info->AutoTunnelNAT.ExternalAddress = m->ExternalAddress;
+ info->AutoTunnelNAT.ExternalPort = zeroIPPort;
+ info->AutoTunnelNAT.Lifetime = 0;
+ info->AutoTunnelNAT.Result = mStatus_NoError;
+ mDNS_DropLockBeforeCallback(); // Allow client to legally make mDNS API calls from the callback
+ info->AutoTunnelNAT.clientCallback(m, &info->AutoTunnelNAT);
+ mDNS_ReclaimLockAfterCallback(); // Decrement mDNS_reentrancy to block mDNS API calls again
+ }
+ info->AutoTunnelNAT.clientContext = mDNSNULL;
}
- info->AutoTunnelNAT.clientContext = mDNSNULL;
+ RemoveAutoTunnelDomainStatus(info);
}
info = info->next;
}
CFRelease(vers);
}
if (!major) { major=8; LogMsg("Note: No Major Build Version number found; assuming 8"); }
- if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, mDNSResponderVersionString);
+ if (HINFO_SWstring) mDNS_snprintf(HINFO_SWstring, 256, "%s %s (%s), %s", prodname, prodvers, buildver, STRINGIFY(mDNSResponderVersion));
return(major);
}
CloseSocketSet(&m->p->permanentsockets);
#if APPLE_OSX_mDNSResponder
+ // clean up tunnels
+ while (m->TunnelClients)
+ {
+ ClientTunnel *cur = m->TunnelClients;
+ LogOperation("mDNSPlatformClose: removing client tunnel %p %##s from list", cur, cur->dstname.c);
+ if (cur->q.ThisQInterval >= 0) mDNS_StopQuery(m, &cur->q);
+ AutoTunnelSetKeys(cur, mDNSfalse);
+ m->TunnelClients = cur->next;
+ freeL("ClientTunnel", cur);
+ }
+
+ if (AnonymousRacoonConfig)
+ {
+ AnonymousRacoonConfig = mDNSfalse;
+ LogOperation("mDNSPlatformClose: Deconfiguring autotunnel");
+ (void)mDNSConfigureServer(kmDNSDown, "");
+ }
+
if (m->AutoTunnelHostAddrActive && m->AutoTunnelHostAddr.b[0])
{
m->AutoTunnelHostAddrActive = mDNSfalse;
- LogMsg("Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
+ LogOperation("mDNSPlatformClose: Removing AutoTunnel address %.16a", &m->AutoTunnelHostAddr);
(void)mDNSAutoTunnelInterfaceUpDown(kmDNSDown, m->AutoTunnelHostAddr.b);
}
#endif // APPLE_OSX_mDNSResponder
}
mDNSexport mDNSs32 mDNSPlatformOneSecond = 1000;
+mDNSexport mDNSu32 mDNSPlatformClockDivisor = 0;
mDNSexport mStatus mDNSPlatformTimeInit(void)
{
// When we ship Macs with clock frequencies above 1000GHz, we may have to update this code.
struct mach_timebase_info tbi;
kern_return_t result = mach_timebase_info(&tbi);
- if (result == KERN_SUCCESS) clockdivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
+ if (result == KERN_SUCCESS) mDNSPlatformClockDivisor = ((uint64_t)tbi.denom * 1000000) / tbi.numer;
return(result);
}
mDNSexport mDNSs32 mDNSPlatformRawTime(void)
{
- if (clockdivisor == 0) { LogMsg("mDNSPlatformRawTime called before mDNSPlatformTimeInit"); return(0); }
+ if (mDNSPlatformClockDivisor == 0) { LogMsg("mDNSPlatformRawTime called before mDNSPlatformTimeInit"); return(0); }
static uint64_t last_mach_absolute_time = 0;
//static uint64_t last_mach_absolute_time = 0x8000000000000000LL; // Use this value for testing the alert display
}
last_mach_absolute_time = this_mach_absolute_time;
- return((mDNSs32)(this_mach_absolute_time / clockdivisor));
+ return((mDNSs32)(this_mach_absolute_time / mDNSPlatformClockDivisor));
}
mDNSexport mDNSs32 mDNSPlatformUTC(void)
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
; $Log: mDNSResponder.sb,v $
+; Revision 1.25 2008/03/17 18:04:41 mcguire
+; <rdar://problem/5800476> SC now reads preference file
+;
; Revision 1.24 2007/09/20 22:33:17 cheshire
; Tidied up inconsistent and error-prone naming -- used to be mDNSResponderHelper in
; some places and mDNSResponder.helper in others; now mDNSResponderHelper everywhere
(allow file-read-data (regex "^/usr/share/icu/.*\$"))
(allow file-read-data (regex "^/usr/share/zoneinfo/.*\$"))
(allow file-read-data (regex "^/System/Library/CoreServices/SystemVersion.*\$"))
+(allow file-read-data (regex "^/Library/Preferences/SystemConfiguration/preferences\.plist\$"))
(allow file-read-data (regex "^/Library/Preferences/(ByHost/)?\.GlobalPreferences.*\.plist\$"))
(allow file-read-data (regex "^/Library/Preferences/com\.apple\.security.*\.plist\$"))
(allow file-read-data (regex "^/Library/Preferences/com\.apple\.crypto\.plist\$"))
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
HEADER_SEARCH_PATHS = (
../mDNSShared,
+ "${SYSTEM_LIBRARY_DIR}/Frameworks/System.framework/PrivateHeaders",
"${APPLE_INTERNAL_DEVELOPER_DIR}/Headers",
"${CONFIGURATION_TEMP_DIR}",
);
);
HEADER_SEARCH_PATHS = (
../mDNSShared,
+ "${SYSTEM_LIBRARY_DIR}/Frameworks/System.framework/PrivateHeaders",
"${APPLE_INTERNAL_DEVELOPER_DIR}/Headers",
"${CONFIGURATION_TEMP_DIR}",
);
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
HEADER_SEARCH_PATHS = ../mDNSShared;
INSTALL_PATH = /usr/bin;
- MACOSX_DEPLOYMENT_TARGET = 10.3;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = "-no-cpp-precomp";
OTHER_LDFLAGS = "";
OTHER_REZFLAGS = "";
Change History (most recent first):
$Log: PlatformCommon.c,v $
+Revision 1.17 2008/03/05 00:19:09 cheshire
+Conditionalize LogTimeStamps so it's specific to APPLE_OSX, for now
+
+Revision 1.16 2008/02/26 21:47:45 cheshire
+Added cast to avoid compiler warning
+
+Revision 1.15 2008/02/26 21:42:26 cheshire
+Added 'LogTimeStamps' option, to show ms-granularity timestamps on every log message
+
Revision 1.14 2007/12/03 18:37:26 cheshire
Moved mDNSPlatformWriteLogMsg & mDNSPlatformWriteDebugMsg
from mDNSMacOSX.c to PlatformCommon.c, so that Posix build can use them
if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf;
if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf;
buf[0] = 0;
- GetConfigOption(buf, "secret-64", f); // failure means no authentication
+ GetConfigOption(buf, "secret-64", f); // failure means no authentication
fclose(f);
f = NULL;
}
badf:
LogMsg("ERROR: malformatted config file");
- if (f) fclose(f);
+ if (f) fclose(f);
}
#if MDNS_DEBUGMSGS
-mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
+mDNSexport void mDNSPlatformWriteDebugMsg(const char *msg)
{
fprintf(stderr,"%s\n", msg);
fflush(stderr);
}
#endif
-mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, int logoptflags)
+mDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, int logoptflags)
{
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+ extern mDNS mDNSStorage;
+ extern mDNSu32 mDNSPlatformClockDivisor;
+ mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0;
+ int ms = ((t < 0) ? -t : t) % 1000;
+#endif
+
if (mDNS_DebugMode) // In debug mode we write to stderr
{
- fprintf(stderr,"%s\n", buffer);
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+ if (mDNSPlatformClockDivisor)
+ fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer);
+ else
+#endif
+ fprintf(stderr,"%s\n", buffer);
fflush(stderr);
}
else // else, in production mode, we write to syslog
{
openlog(ident, LOG_CONS | logoptflags, LOG_DAEMON);
- syslog(LOG_ERR, "%s", buffer);
+#if APPLE_OSX_mDNSResponder && LogTimeStamps
+ if (mDNSPlatformClockDivisor)
+ syslog(LOG_ERR, "%8d.%03d: %s", (int)(t/1000), ms, buffer);
+ else
+#endif
+ syslog(LOG_ERR, "%s", buffer);
closelog();
}
}
*/
#ifndef _DNS_SD_H
-#define _DNS_SD_H 1700000
+#define _DNS_SD_H 1710400
#ifdef __cplusplus
extern "C" {
kDNSServiceErr_BadKey = -65561,
kDNSServiceErr_Transient = -65562,
kDNSServiceErr_ServiceNotRunning = -65563, /* Background daemon not running */
- kDNSServiceErr_NATPortMappingUnsupported = -65564, /* No NAT or if the NAT doesn't support NAT-PMP or UPnP. */
- kDNSServiceErr_NATPortMappingDisabled = -65565 /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+ kDNSServiceErr_NATPortMappingUnsupported = -65564, /* NAT doesn't support NAT-PMP or UPnP */
+ kDNSServiceErr_NATPortMappingDisabled = -65565, /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
+ kDNSServiceErr_NoRouter = -65566, /* No router currently configured (probably no network connectivity) */
+ kDNSServiceErr_PollingMode = -65567
/* mDNS Error codes are in the range
* FFFE FF00 (-65792) to FFFE FFFF (-65537) */
*
* interfaceIndex: The interface through which the NAT gateway is reached.
*
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are
- * undefined if errorCode is nonzero.
+ * errorCode: Will be kDNSServiceErr_NoError on success.
+ * Will be kDNSServiceErr_DoubleNAT when the NAT gateway is itself behind one or
+ * more layers of NAT, in which case the other parameters have the defined values.
+ * For other failures, will indicate the failure that occurred, and the other
+ * parameters are undefined.
*
* publicAddress: Four byte IPv4 address in network byte order.
*
Change History (most recent first):
$Log: dnsextd.c,v $
+Revision 1.88 2008/03/06 21:26:11 cheshire
+Moved duplicated STRINGIFY macro from individual C files to DNSCommon.h
+
Revision 1.87 2007/12/17 23:34:50 cheshire
Don't need to set ptr to result of DNSDigest_SignMessage -- ptr is updated anyway (it's passed by reference)
mDNS mDNSStorage;
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) #s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
// For convenience when using the "strings" command, this is the last thing in the file
// The "@(#) " pattern is a special prefix the "what" command looks for
const char mDNSResponderVersionString_SCCS[] = "@(#) dnsextd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
Change History (most recent first):
$Log: dnssd_clientstub.c,v $
+Revision 1.102 2008/02/25 19:16:19 cheshire
+<rdar://problem/5708953> Problems with DNSServiceGetAddrInfo API
+Was returning a bogus result (NULL pointer) when following a CNAME referral
+
+Revision 1.101 2008/02/20 21:18:21 cheshire
+<rdar://problem/5708953> DNSServiceGetAddrInfo doesn't set the scope ID of returned IPv6 link local addresses
+
Revision 1.100 2007/11/02 17:56:37 cheshire
<rdar://problem/5565787> Bonjour API broken for 64-bit apps (SCM_RIGHTS sendmsg fails)
Wrap hack code in "#if APPLE_OSX_mDNSResponder" since (as far as we know right now)
static void handle_addrinfo_response(DNSServiceOp *sdr, CallbackHeader *cbh, char *data, char *end)
{
- uint32_t ttl;
char hostname[kDNSServiceMaxDomainName];
uint16_t rrtype, rrclass, rdlen;
char *rdata;
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- struct sockaddr * sa = NULL;
+ uint32_t ttl;
get_string(&data, end, hostname, kDNSServiceMaxDomainName);
rrtype = get_uint16(&data, end);
rrclass = get_uint16(&data, end);
rdlen = get_uint16(&data, end);
- rdata = get_rdata(&data, end, rdlen);
+ rdata = get_rdata (&data, end, rdlen);
ttl = get_uint32(&data, end);
-
+
+ // We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
+ // those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
+ // Other result types, specifically CNAME referrals, are not communicated to the client, because
+ // the DNSServiceGetAddrInfoReply interface doesn't have any meaningful way to communiate CNAME referrals.
if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_addrinfo_response: error reading result from daemon");
- else
+ else if (rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_AAAA)
{
+ struct sockaddr_in sa4;
+ struct sockaddr_in6 sa6;
+ const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
if (rrtype == kDNSServiceType_A)
{
- sa = (struct sockaddr *)&sa4;
bzero(&sa4, sizeof(sa4));
#ifndef NOT_HAVE_SA_LEN
- sa->sa_len = sizeof(struct sockaddr_in);
+ sa4.sin_len = sizeof(struct sockaddr_in);
#endif
- sa->sa_family = AF_INET;
+ sa4.sin_family = AF_INET;
+ // sin_port = 0;
if (!cbh->cb_err) memcpy(&sa4.sin_addr, rdata, rdlen);
}
- else if (rrtype == kDNSServiceType_AAAA)
+ else
{
- sa = (struct sockaddr *)&sa6;
bzero(&sa6, sizeof(sa6));
#ifndef NOT_HAVE_SA_LEN
- sa->sa_len = sizeof(struct sockaddr_in6);
+ sa6.sin6_len = sizeof(struct sockaddr_in6);
#endif
- sa->sa_family = AF_INET6;
- if (!cbh->cb_err) memcpy(&sa6.sin6_addr, rdata, rdlen);
+ sa6.sin6_family = AF_INET6;
+ // sin6_port = 0;
+ // sin6_flowinfo = 0;
+ // sin6_scope_id = 0;
+ if (!cbh->cb_err)
+ {
+ memcpy(&sa6.sin6_addr, rdata, rdlen);
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr)) sa6.sin6_scope_id = cbh->cb_interface;
+ }
}
((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, hostname, sa, ttl, sdr->AppContext);
// MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
Change History (most recent first):
$Log: uds_daemon.c,v $
+Revision 1.387 2008/02/26 21:24:13 cheshire
+Fixed spelling mistake in comment
+
+Revision 1.386 2008/02/26 20:23:15 cheshire
+Updated comments
+
+Revision 1.385 2008/02/19 21:50:52 cheshire
+Shortened some overly-long lines
+
Revision 1.384 2007/12/22 01:38:05 cheshire
Improve display of "Auth Records" SIGINFO output
{
struct registered_record_entry *next;
mDNSu32 key;
- AuthRecord *rr; // Variable-sized AuthRecord
+ AuthRecord *rr; // Pointer to variable-sized AuthRecord
client_context_t client_context;
request_state *request;
} registered_record_entry;
mDNSBool clientnotified; // Has client been notified of successful registration yet?
mDNSBool default_local; // is this the "local." from an empty-string registration?
domainname domain;
- ServiceRecordSet srs; // note - must be last field in struct
+ ServiceRecordSet srs; // note -- variable-sized object -- must be last field in struct
} service_instance;
// for multi-domain default browsing
transfer_state ts;
mDNSu32 hdr_bytes; // bytes of header already read
ipc_msg_hdr hdr;
- mDNSu32 data_bytes; // bytes of message data already read
+ mDNSu32 data_bytes; // bytes of message data already read
char *msgbuf; // pointer to data storage to pass to free()
char *msgptr; // pointer to data to be read from (may be modified)
char *msgend; // pointer to byte after last byte of message
{ LogMsg("register_service_instance: domain %##s already registered", domain->c); return mStatus_AlreadyRegistered; }
}
- // Special-case hack: We don't advertise SMB service in AutoTunnel domains, because AutoTunnel services have to support IPv6, and our SMB server does not
+ // Special-case hack: We don't advertise SMB service in AutoTunnel domains, because AutoTunnel
+ // services have to support IPv6, and our SMB server does not
// <rdar://problem/5482322> BTMM: Don't advertise SMB with BTMM because it doesn't support IPv6
if (SameDomainName(&request->u.servicereg.type, (const domainname *) "\x4" "_smb" "\x4" "_tcp"))
{
// to the mDNSCore routine) that sends results back to the client, and a termination routine that aborts
// the mDNSCore operation if the client dies or closes its socket.
-// query and resolve calls have separate request handlers that parse the arguments from the client and
-// massage the name parameters appropriately, but the rest of the operations (making the query call,
-// delivering the result to the client, and termination) are identical.
-
-// what gets called when a resolve is completed and we need to send the data back to the client
mDNSlocal void queryrecord_result_callback(mDNS *const m, DNSQuestion *question, const ResourceRecord *const answer, QC_result AddRecord)
{
char name[MAX_ESCAPED_DOMAIN_NAME];
rrtype = get_uint16(&request->msgptr, request->msgend);
rrclass = get_uint16(&request->msgptr, request->msgend);
- if (!request->msgptr) { LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ if (!request->msgptr)
+ { LogMsg("%3d: DNSServiceQueryRecord(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
mDNSPlatformMemZero(&request->u.queryrecord.q, sizeof(&request->u.queryrecord.q));
mDNSInterfaceID InterfaceID = mDNSPlatformInterfaceIDfromInterfaceIndex(&mDNSStorage, interfaceIndex);
if (interfaceIndex && !InterfaceID) return(mStatus_BadParamErr);
- if (!request->msgptr) { LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ if (!request->msgptr)
+ { LogMsg("%3d: DNSServiceEnumerateDomains(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
// allocate context structures
uDNS_RegisterSearchDomains(&mDNSStorage);
ttl = get_uint32(&request->msgptr, request->msgend);
}
- if (!request->msgptr) { LogMsg("%3d: DNSServiceNATPortMappingCreate(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
+ if (!request->msgptr)
+ { LogMsg("%3d: DNSServiceNATPortMappingCreate(unreadable parameters)", request->sd); return(mStatus_BadParamErr); }
if (protocol == 0) // If protocol == 0 (i.e. just request public address) then IntPort, ExtPort, ttl must be zero too
{
mDNS_GetDomains(&mDNSStorage, &mDNSStorage.AutomaticBrowseDomainQ, mDNS_DomainTypeBrowseAutomatic,
mDNSNULL, mDNSInterface_LocalOnly, AutomaticBrowseDomainChange, mDNSNULL);
- RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeRegistration); // Add "local" as recommended registration domain ("dns-sd -E")
- RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeBrowse); // Add "local" as recommended browsing domain ("dns-sd -F")
- AddAutoBrowseDomain(0, &localdomain); // Add "local" as automatic browsing domain
+ // Add "local" as recommended registration domain ("dns-sd -E"), recommended browsing domain ("dns-sd -F"), and automatic browsing domain
+ RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeRegistration);
+ RegisterLocalOnlyDomainEnumPTR(&mDNSStorage, &localdomain, mDNS_DomainTypeBrowse);
+ AddAutoBrowseDomain(0, &localdomain);
udsserver_handle_configchange(&mDNSStorage);
return 0;
{
ClientTunnel *c;
for (c = m->TunnelClients; c; c = c->next)
- LogMsgNoIdent("%##s local %.16a %.4a remote %.16a %.4a %5d interval %d", c->dstname.c, &c->loc_inner, &c->loc_outer, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), c->q.ThisQInterval);
+ LogMsgNoIdent("%##s local %.16a %.4a remote %.16a %.4a %5d interval %d",
+ c->dstname.c, &c->loc_inner, &c->loc_outer, &c->rmt_inner, &c->rmt_outer, mDNSVal16(c->rmt_outer_port), c->q.ThisQInterval);
}
#endif
}