/*\r
* Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.\r
*\r
- * @APPLE_LICENSE_HEADER_START@\r
- * \r
- * This file contains Original Code and/or Modifications of Original Code\r
- * as defined in and that are subject to the Apple Public Source License\r
- * Version 2.0 (the 'License'). You may not use this file except in\r
- * compliance with the License. Please obtain a copy of the License at\r
- * http://www.opensource.apple.com/apsl/ and read it before using this\r
- * file.\r
- * \r
- * The Original Code and all software distributed under the License are\r
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER\r
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,\r
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.\r
- * Please see the License for the specific language governing rights and\r
- * limitations under the License.\r
- * \r
- * @APPLE_LICENSE_HEADER_END@\r
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
\r
Change History (most recent first):\r
\r
include /Developer/Makefiles/pb_makefiles/platform.make
-MVERS = "mDNSResponder-107.3"
+MVERS = "mDNSResponder-107.4"
install:
cd "$(SRCROOT)/mDNSMacOSX"; xcodebuild install OBJROOT=$(OBJROOT) SYMROOT=$(SYMROOT) DSTROOT=$(DSTROOT) MVERS=$(MVERS)
Change History (most recent first):
$Log: mDNS.c,v $
+Revision 1.526 2005/10/20 00:10:33 cheshire
+<rdar://problem/4290265> Add check to avoid crashing NAT gateways that have buggy DNS relay code
+
+Revision 1.525 2005/09/24 00:47:17 cheshire
+Fix comment typos
+
+Revision 1.524 2005/09/16 21:06:49 cheshire
+Use mDNS_TimeNow_NoLock macro, instead of writing "mDNSPlatformRawTime() + m->timenow_adjust" all over the place
+
+Revision 1.523 2005/03/21 00:33:51 shersche
+<rdar://problem/4021486> Fix build warnings on Win32 platform
+
Revision 1.522 2005/03/04 21:48:12 cheshire
<rdar://problem/4037283> Fractional time rounded down instead of up on platforms with coarse clock granularity
mDNSexport const mDNSOpaque16 zeroID = { { 0, 0 } };
mDNSexport const mDNSOpaque16 QueryFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery, 0 } };
+mDNSexport const mDNSOpaque16 uQueryFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_StdQuery | kDNSFlag0_RD, 0 } };
mDNSexport const mDNSOpaque16 ResponseFlags = { { kDNSFlag0_QR_Response | kDNSFlag0_OP_StdQuery | kDNSFlag0_AA, 0 } };
mDNSexport const mDNSOpaque16 UpdateReqFlags= { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Update, 0 } };
mDNSexport const mDNSOpaque16 UpdateRespFlags={ { kDNSFlag0_QR_Response | kDNSFlag0_OP_Update, 0 } };
mDNSu32 nwritten = 0;
int c;
if (buflen == 0) return(0);
- buflen--; // Pre-reserve one space in the buffer for the terminating nul
+ buflen--; // Pre-reserve one space in the buffer for the terminating null
if (buflen == 0) goto exit;
for (c = *fmt; c != 0; c = *++fmt)
newptr = PutResourceRecordTTL(&m->omsg, responseptr, &m->omsg.h.numAnswers, &rr->resrec, m->SleepState ? 0 : rr->resrec.rroriginalttl);
rr->resrec.rrclass &= ~kDNSClass_UniqueRRSet; // Make sure to clear cache flush bit back to normal state
if (!newptr && m->omsg.h.numAnswers) break;
- rr->RequireGoodbye = !m->SleepState;
+ rr->RequireGoodbye = (mDNSu8) (!m->SleepState);
if (rr->LastAPTime == m->timenow) numAnnounce++; else numAnswer++;
responseptr = newptr;
}
}
if (m->timenow) time = m->timenow;
- else time = mDNSPlatformRawTime() + m->timenow_adjust;
+ else time = mDNS_TimeNow_NoLock(m);
mDNSPlatformUnlock(m);
return(time);
}
if (!ValidateDomainName(&question->qname))
{
- LogMsg("Attempt to start query with invalid qname %##s %s", question->qname.c, DNSTypeName(question->qtype));
+ LogMsg("Attempt to start query with invalid qname %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
return(mStatus_Invalid);
}
question->LastQTxTime = m->timenow;
if (!question->DuplicateOf)
- verbosedebugf("mDNS_StartQuery_internal: Question %##s %s %p %d (%p) started",
+ verbosedebugf("mDNS_StartQuery_internal: Question %##s (%s) %p %d (%p) started",
question->qname.c, DNSTypeName(question->qtype), question->InterfaceID, question->LastQTime + question->ThisQInterval - m->timenow, question);
else
- verbosedebugf("mDNS_StartQuery_internal: Question %##s %s %p %d (%p) duplicate of (%p)",
+ verbosedebugf("mDNS_StartQuery_internal: 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);
*q = question;
#ifndef UNICAST_DISABLED
// If the client has specified an explicit InterfaceID,
- // then we do a multicast registration on that interface, even for unicast domains.
+ // then we do a multicast registration on that interface, even for unicast domains.
if (!(InterfaceID == mDNSInterface_LocalOnly || IsLocalDomain(sr->RR_SRV.resrec.name)))
{
mStatus status;
mDNSBool AdvertiseLocalAddresses, mDNSCallback *Callback, void *Context)
{
mDNSu32 slot;
- mDNSs32 timenow, timenow_adjust;
+ mDNSs32 timenow;
mStatus result;
if (!rrcachestorage) rrcachesize = 0;
// Task Scheduling variables
result = mDNSPlatformTimeInit();
if (result != mStatus_NoError) return(result);
- timenow_adjust = (mDNSs32)mDNSRandom(0xFFFFFFFF);
- timenow = mDNSPlatformRawTime() + timenow_adjust;
+ m->timenow_adjust = (mDNSs32)mDNSRandom(0xFFFFFFFF);
+ timenow = mDNS_TimeNow_NoLock(m);
m->timenow = 0; // MUST only be set within mDNS_Lock/mDNS_Unlock section
m->timenow_last = timenow;
- m->timenow_adjust = timenow_adjust;
m->NextScheduledEvent = timenow;
m->SuppressSending = timenow;
m->NextCacheCheck = timenow + 0x78000000;
#ifndef UNICAST_DISABLED
uDNS_Init(m);
+ m->SuppressStdPort53Queries = 0;
#endif
result = mDNSPlatformInit(m);
Change History (most recent first):
$Log: mDNSEmbeddedAPI.h,v $
+Revision 1.287 2005/10/20 00:10:33 cheshire
+<rdar://problem/4290265> Add check to avoid crashing NAT gateways that have buggy DNS relay code
+
+Revision 1.286 2005/09/24 01:09:40 cheshire
+Fix comment typos
+
+Revision 1.285 2005/09/16 20:57:47 cheshire
+Add macro mDNS_TimeNow_NoLock(m) to get properly adjusted time without also acquiring lock
+
Revision 1.284 2005/07/29 18:04:22 ksekar
<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
// For records containing a hostname (in the name on the left, or in the rdata on the right),
// like A, AAAA, reverse-mapping PTR, and SRV, we use a two-minute TTL by default, because we don't want
// them to hang around for too long in the cache if the host in question crashes or otherwise goes away.
-// Wide-area service discovery records have a very short TTL to aviod poluting intermediate caches with
+// Wide-area service discovery records have a very short TTL to avoid poluting intermediate caches with
// dynamic records. When discovered via Long Lived Queries (with change notifications), resource record
// TTLs can be safely ignored.
const void *StatusContext; // Client Context
} uDNS_HostnameInfo;
+enum
+ {
+ DNSServer_Untested = 0,
+ DNSServer_Failed = 1,
+ DNSServer_Passed = 2
+ };
+
typedef struct DNSServer
{
struct DNSServer *next;
- mDNSAddr addr;
- domainname domain; // name->server matching for "split dns"
- int flag; // temporary marker for list intersection
+ mDNSAddr addr;
+ mDNSBool del; // Set when we're planning to delete this from the list
+ mDNSu32 teststate; // Have we sent bug-detection query to this server?
+ domainname domain; // name->server matching for "split dns"
} DNSServer;
typedef struct NetworkInterfaceInfo_struct NetworkInterfaceInfo;
domainname ServiceRegDomain; // (going away w/ multi-user support)
struct uDNS_AuthInfo *AuthInfoList; // list of domains requiring authentication for updates.
uDNS_HostnameInfo *Hostnames; // List of registered hostnames + hostname metadata
- DNSQuestion ReverseMap; // Reverse-map query to find static hostname for service target
+ DNSQuestion ReverseMap; // Reverse-map query to find static hostname for service target
mDNSBool ReverseMapActive; // Is above query active?
domainname StaticHostname; // Current answer to reverse-map query (above)
mDNSBool DelaySRVUpdate; // Delay SRV target/port update to avoid "flap"
char MsgBuffer[80]; // Temp storage used while building error log messages
// Task Scheduling variables
+ mDNSs32 timenow_adjust; // Correction applied if we ever discover time went backwards
mDNSs32 timenow; // The time that this particular activation of the mDNS code started
mDNSs32 timenow_last; // The time the last time we ran
- mDNSs32 timenow_adjust; // Correction applied if we ever discover time went backwards
mDNSs32 NextScheduledEvent; // Derived from values below
mDNSs32 SuppressSending; // Don't send *any* packets during this time
mDNSs32 NextCacheCheck; // Next time to refresh cache record before it expires
// unicast-specific data
uDNS_GlobalInfo uDNS_info;
+ mDNSs32 SuppressStdPort53Queries; // Wait before allowing the next standard unicast query to the user's configured DNS server
// Fixed storage, to avoid creating large objects on the stack
DNSMessage imsg; // Incoming message received from wire
extern const mDNSOpaque16 zeroID;
extern const mDNSOpaque16 QueryFlags;
+extern const mDNSOpaque16 uQueryFlags;
extern const mDNSOpaque16 ResponseFlags;
extern const mDNSOpaque16 UpdateReqFlags;
extern const mDNSOpaque16 UpdateRespFlags;
// mDNS_AddRecordToService adds an additional record to a Service Record Set. This record may be deregistered
// via mDNS_RemoveRecordFromService, or by deregistering the service. mDNS_RemoveRecordFromService is passed a
// callback to free the memory associated with the extra RR when it is safe to do so. The ExtraResourceRecord
-// object can be found in the record's context pointer.
+// object can be found in the record's context pointer.
// mDNS_GetBrowseDomains is a special case of the mDNS_StartQuery call, where the resulting answers
// are a list of PTR records indicating (in the rdata) domains that are recommended for browsing.
#pragma mark - Other utility functions and macros
#endif
+// mDNS_vsnprintf/snprintf return the number of characters written, excluding the final terminating null.
+// The output is always null-terminated: for example, if the output turns out to be exactly buflen long,
+// then the output will be truncated by one character to allow space for the terminating null.
+// Unlike standard C vsnprintf/snprintf, they return the number of characters *actually* written,
+// not the number of characters that *would* have been printed were buflen unlimited.
extern mDNSu32 mDNS_vsnprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, va_list arg);
extern mDNSu32 mDNS_snprintf(char *sbuffer, mDNSu32 buflen, const char *fmt, ...) IS_A_PRINTF_STYLE_FUNCTION(3,4);
extern mDNSu32 NumCacheRecordsForInterfaceID(const mDNS *const m, mDNSInterfaceID id);
// Generally speaking:
// Code that's protected by the main mDNS lock should just use the m->timenow value
// Code outside the main mDNS lock should use mDNS_TimeNow(m) to get properly adjusted time
+// In certain cases there may be reasons why it's necessary to get the time without taking the lock first
+// (e.g. inside the routines that are doing the locking and unlocking, where a call to get the lock would result in a
+// recursive loop); in these cases use mDNS_TimeNow_NoLock(m) to get mDNSPlatformRawTime with the proper correction factor added.
//
// mDNSPlatformUTC returns the time, in seconds, since Jan 1st 1970 UTC and is required for generating TSIG records
extern mStatus mDNSPlatformTimeInit (void);
extern mDNSs32 mDNSPlatformRawTime (void);
extern mDNSs32 mDNSPlatformUTC (void);
+#define mDNS_TimeNow_NoLock(m) (mDNSPlatformRawTime() + m->timenow_adjust)
// Platform support modules should provide the following functions to map between opaque interface IDs
// and interface indexes in order to support the DNS-SD API. If your target platform does not support
Change History (most recent first):
$Log: uDNS.c,v $
+Revision 1.225 2005/10/21 22:51:17 cheshire
+<rdar://problem/4290265> Add check to avoid crashing NAT gateways that have buggy DNS relay code
+Refinement: Shorten "check-for-broken-dns-relay" to just "dnsbugtest"
+to avoid crashing NAT gateways that have a different DNS relay bug
+
+Revision 1.224 2005/10/20 00:10:33 cheshire
+<rdar://problem/4290265> Add check to avoid crashing NAT gateways that have buggy DNS relay code
+
+Revision 1.223 2005/10/17 18:52:42 cheshire
+<rdar://problem/4271183> mDNSResponder crashed in CheckRecordRegistrations
+Move code to unregister the service's extra records from uDNS_DeregisterService() to unlinkSRS().
+
+Revision 1.222 2005/10/05 23:04:10 cheshire
+Add more information to unlinkAR and startLLQHandshakeCallback error messages
+
+Revision 1.221 2005/10/05 17:27:48 herscher
+<rdar://problem/4272516> Change 200ms delay to 10ms
+
+Revision 1.220 2005/09/24 01:10:09 cheshire
+Fix comment typos
+
+Revision 1.219 2005/09/22 07:28:25 herscher
+Double the delay to 200000 usec after sending out a DNS query
+
+Revision 1.218 2005/09/13 01:06:14 herscher
+<rdar://problem/4248878> Add 100ms delay in sendQuery.
+
Revision 1.217 2005/08/04 18:08:24 cheshire
Update comments
// unlink an AuthRecord from a linked list
mDNSlocal mStatus unlinkAR(AuthRecord **list, AuthRecord *const rr)
{
- AuthRecord *rptr, *prev = mDNSNULL;
-
- for (rptr = *list; rptr; rptr = rptr->next)
- {
- if (rptr == rr)
- {
- if (prev) prev->next = rptr->next;
- else *list = rptr->next;
- rptr->next = mDNSNULL;
- return mStatus_NoError;
- }
- prev = rptr;
- }
- LogMsg("ERROR: unlinkAR - no such active record");
- return mStatus_UnknownErr;
+ while (*list && *list != rr) list = &(*list)->next;
+ if (*list) { *list = rr->next; rr->next = mDNSNULL; return(mStatus_NoError); }
+ LogMsg("ERROR: unlinkAR - no such active record %##s", rr->resrec.name->c);
+ return(mStatus_NoSuchRecord);
}
mDNSlocal void unlinkSRS(mDNS *m, ServiceRecordSet *srs)
}
else n = n->next;
}
-
+
for (p = &u->ServiceRegistrations; *p; p = &(*p)->next)
- if (*p == srs) { *p = srs->next; srs->next = mDNSNULL; return; }
- LogMsg("ERROR: unlinkSRS - SRS not found in ServiceRegistrations list");
+ if (*p == srs)
+ {
+ ExtraResourceRecord *e;
+ *p = srs->next;
+ srs->next = mDNSNULL;
+ for (e=srs->Extras; e; e=e->next)
+ if (unlinkAR(&u->RecordRegistrations, &e->r))
+ LogMsg("unlinkSRS: extra record %##s not found", e->r.resrec.name->c);
+ return;
+ }
+ LogMsg("ERROR: unlinkSRS - SRS not found in ServiceRegistrations list %##s", srs->RR_SRV.resrec.name->c);
}
mDNSlocal void LinkActiveQuestion(uDNS_GlobalInfo *u, DNSQuestion *q)
// allocate, add to list
s = umalloc(sizeof(*s));
if (!s) { LogMsg("Error: mDNS_AddDNSServer - malloc"); goto end; }
- s->addr = *addr;
+ s->addr = *addr;
+ s->del = mDNSfalse;
+ s->teststate = DNSServer_Untested;
AssignDomainName(&s->domain, d);
s->next = mDNSNULL;
*p = s;
return;
}
-// if LLQ NAT context unreferenced, delete the mapping
+// if LLQ NAT context unreferenced, delete the mapping
mDNSlocal void CheckForUnreferencedLLQMapping(mDNS *m)
{
NATTraversalInfo *nat = m->uDNS_info.LLQNatInfo;
{
LogMsg("ERROR: AssignHostnameInfoAuthRecord - overwriting %s AuthRec", type == mDNSAddrType_IPv4 ? "IPv4" : "IPv6");
unlinkAR(&u->RecordRegistrations, *dst);
- (*dst)->RecordContext = mDNSNULL; // defensively clear backpointer to aviod doubly-referenced context
+ (*dst)->RecordContext = mDNSNULL; // defensively clear backpointer to avoid doubly-referenced context
}
*dst = ar;
}
-// Deregister hostnames and register new names for each host domain with the current global
+// Deregister hostnames and register new names for each host domain with the current global
// values for the hostlabel and primary IP address
mDNSlocal void UpdateHostnameRegistrations(mDNS *m)
{
}
}
else if (!followedCName || !SameDomainName(cr->resrec.name, &origname))
- LogMsg("Question %##s %X %s %##s- unexpected answer %##s %X %s",
+ LogMsg("Question %##s %X (%s) %##s unexpected answer %##s %X (%s)",
question->qname.c, question->qnamehash, DNSTypeName(question->qtype), origname.c,
cr->resrec.name->c, cr->resrec.namehash, DNSTypeName(cr->resrec.rrtype));
}
}
}
+mDNSlocal const domainname *DNSRelayTestQuestion = (domainname*)
+ "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\xa" "dnsbugtest"
+ "\x1" "1" "\x1" "0" "\x1" "0" "\x3" "127" "\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 mDNSInterfaceID InterfaceID)
+ {
+ const mDNSu8 *ptr = msg->data;
+ DNSQuestion q;
+ DNSServer *s;
+ mDNSu32 result = 0;
+ mDNSBool found = mDNSfalse;
+
+ // 1. Find out if this is an answer to one of our test questions
+ if (msg->h.numQuestions != 1) return(mDNSfalse);
+ ptr = getQuestion(msg, ptr, end, InterfaceID, &q);
+ if (!ptr) return(mDNSfalse);
+ if (q.qtype != kDNSType_PTR || q.qclass != kDNSClass_IN) return(mDNSfalse);
+ if (!SameDomainName(&q.qname, DNSRelayTestQuestion)) return(mDNSfalse);
+
+ // 2. If the DNS relay gave us a positive response, then it's got buggy firmware
+ // else, if the DNS relay gave us an error or no-answer response, it passed our test
+ if ((msg->h.flags.b[1] & kDNSFlag1_RC) == kDNSFlag1_RC_NoErr && msg->h.numAnswers > 0)
+ result = DNSServer_Failed;
+ else
+ result = DNSServer_Passed;
+
+ // 3. Find occurrences of this server in our list, and mark them appropriately
+ for (s = m->uDNS_info.Servers; s; s = s->next)
+ if (mDNSSameAddress(srcaddr, &s->addr) && s->teststate != result)
+ { s->teststate = result; found = mDNStrue; }
+
+ // 4. Assuming we found the server in question in our list (don't want to risk being victim of a deliberate DOS attack here)
+ // log a message to let the user know why Wide-Area Service Discovery isn't working
+ if (found && result == DNSServer_Failed)
+ LogMsg("NOTE: Wide-Area Service Discovery disabled to avoid crashing defective DNS relay %#a.", srcaddr);
+
+ return(mDNStrue); // Return mDNStrue to tell uDNS_ReceiveMsg it doens't need to process this packet further
+ }
+
mDNSexport void uDNS_ReceiveMsg(mDNS *const m, DNSMessage *const msg, const mDNSu8 *const end,
const mDNSAddr *const srcaddr, const mDNSIPPort srcport, const mDNSAddr *const dstaddr,
const mDNSIPPort dstport, const mDNSInterfaceID InterfaceID)
// LLQ Responses over TCP not currently supported
if (srcaddr && recvLLQResponse(m, msg, end, srcaddr, srcport, InterfaceID)) return;
+ if (uDNS_ReceiveTestQuestionResponse(m, msg, end, srcaddr, InterfaceID)) return;
+
for (qptr = u->ActiveQueries; qptr; qptr = qptr->next)
{
//!!!KRS we should have a hashtable, hashed on message id
}
// lookup a DNS Server, matching by name in split-dns configurations. Result stored in addr parameter if successful
-mDNSlocal mDNSBool GetServerForName(uDNS_GlobalInfo *u, const domainname *name, mDNSAddr *addr)
+mDNSlocal DNSServer *GetServerForName(uDNS_GlobalInfo *u, const domainname *name)
{
DNSServer *curmatch = mDNSNULL, *p = u->Servers;
- int i, ncount, scount, curmatchlen = -1;
+ int i, curmatchlen = -1;
+ int ncount = name ? CountLabels(name) : 0;
- *addr = zeroAddr;
- ncount = name ? CountLabels(name) : 0;
while (p)
{
- scount = CountLabels(&p->domain);
+ int scount = CountLabels(&p->domain);
if (scount <= ncount && scount > curmatchlen)
{
// only inspect if server's domain is longer than current best match and shorter than the name itself
}
p = p->next;
}
-
- if (curmatch)
- {
- *addr = curmatch->addr;
- return mDNStrue;
- }
- else return mDNSfalse;
+ return(curmatch);
}
// ***************************************************************************
mDNSlocal void initializeQuery(DNSMessage *msg, DNSQuestion *question)
{
- mDNSOpaque16 flags = QueryFlags;
-
ubzero(msg, sizeof(msg));
- flags.b[0] |= kDNSFlag0_RD; // recursion desired
- InitializeDNSMessage(&msg->h, question->uDNS_info.id, flags);
+ InitializeDNSMessage(&msg->h, question->uDNS_info.id, uQueryFlags);
}
mDNSlocal mStatus constructQueryMsg(DNSMessage *msg, mDNSu8 **endPtr, DNSQuestion *const question)
{ LogMsg("ERROR: startLLQHandshake - bad state %d", info->state); goto error; }
if (err)
- { LogMsg("ERROR: startLLQHandshakeCallback invoked with error code %ld", err); goto poll; }
+ { LogMsg("ERROR: startLLQHandshakeCallback %##s invoked with error code %ld", info->question->qname.c, err); goto poll; }
if (!result)
{ LogMsg("ERROR: startLLQHandshakeCallback invoked with NULL result and no error code"); goto error; }
{ debugf("LLQ port lookup failed - reverting to polling"); info->servPort.NotAnInteger = 0; goto poll; }
// cache necessary zone data
- info->servAddr.type = zoneInfo->primaryAddr.type;
- info->servAddr.ip.v4.NotAnInteger = zoneInfo->primaryAddr.ip.v4.NotAnInteger;
- info->servPort.NotAnInteger = zoneInfo->llqPort.NotAnInteger;
+ info->servAddr = zoneInfo->primaryAddr;
+ info->servPort = zoneInfo->llqPort;
info->ntries = 0;
if (info->state == LLQ_SuspendDeferred) info->state = LLQ_Suspended;
mDNSlocal mStatus startQuery(mDNS *const m, DNSQuestion *const question, mDNSBool internal)
{
uDNS_GlobalInfo *u = &m->uDNS_info;
- DNSMessage msg;
- mDNSu8 *endPtr;
- mStatus err = mStatus_NoError;
- mDNSAddr server;
-
- //!!!KRS we should check if the question is already in our acivequestion list
+ //!!!KRS we should check if the question is already in our activequestion list
if (!ValidateDomainName(&question->qname))
{
- LogMsg("Attempt to start query with invalid qname %##s %##s", question->qname.c, DNSTypeName(question->qtype));
+ LogMsg("Attempt to start query with invalid qname %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
return mStatus_Invalid;
}
// break here if its and LLQ
if (question->LongLived) return startLLQ(m, question);
- // else send the query to our server
- err = constructQueryMsg(&msg, &endPtr, question);
- if (err) return err;
-
- question->LastQTime = mDNSPlatformTimeNow(m);
- question->ThisQInterval = INIT_UCAST_POLL_INTERVAL;
+ question->ThisQInterval = INIT_UCAST_POLL_INTERVAL / 2;
+ question->LastQTime = mDNSPlatformTimeNow(m) - question->ThisQInterval;
// store the question/id in active question list
question->uDNS_info.internal = internal;
LinkActiveQuestion(u, question);
question->uDNS_info.knownAnswers = mDNSNULL;
- if (GetServerForName(u, &question->qname, &server))
- {
- err = mDNSSendDNSMessage(m, &msg, endPtr, mDNSInterface_Any, &server, UnicastDNSPort, -1, mDNSNULL);
- if (err) { debugf("ERROR: startQuery - %ld (keeping question in list for retransmission", err); }
- if (err == mStatus_TransientErr) err = mStatus_NoError; // don't return transient errors to caller
- }
- return err;
+ LogOperation("uDNS startQuery: %##s (%s)", question->qname.c, DNSTypeName(question->qtype));
+
+ return mStatus_NoError;
}
mDNSexport mStatus uDNS_StartQuery(mDNS *const m, DNSQuestion *const question)
}
result.type = zoneDataResult;
- result.zoneData.primaryAddr.ip.v4.NotAnInteger = context->addr.NotAnInteger;
+ result.zoneData.primaryAddr.ip.v4 = context->addr;
result.zoneData.primaryAddr.type = mDNSAddrType_IPv4;
AssignDomainName(&result.zoneData.zoneName, &context->zone);
result.zoneData.zoneClass = context->zoneClass;
}
if (rr->rrtype == kDNSType_A && SameDomainName(&context->ns, rr->name))
{
- context->addr.NotAnInteger = rr->rdata->u.ipv4.NotAnInteger;
+ context->addr = rr->rdata->u.ipv4;
context->state = foundA;
return smContinue;
}
if (!ptr) { LogMsg("ERROR: lookupNSAddr, Answers - GetLargeResourceRecord returned NULL"); break; }
if (rr->rrtype == kDNSType_A && SameDomainName(&context->ns, rr->name))
{
- context->addr.NotAnInteger = rr->rdata->u.ipv4.NotAnInteger;
+ context->addr = rr->rdata->u.ipv4;
context->state = foundA;
return smContinue;
}
if (!ptr) { LogMsg("ERROR: hndlLookupUpdatePort - GetLargeResourceRecord returned NULL"); return smError; }
if (ResourceRecordAnswersQuestion(&lcr.r.resrec, &context->question))
{
- port->NotAnInteger = lcr.r.resrec.rdata->u.srv.port.NotAnInteger;
+ *port = lcr.r.resrec.rdata->u.srv.port;
context->state = foundPort;
return smContinue;
}
id = newMessageID(u);
InitializeDNSMessage(&msg.h, id, UpdateReqFlags);
- rr->uDNS_info.id.NotAnInteger = id.NotAnInteger;
+ rr->uDNS_info.id = id;
// set zone
ptr = putZone(&msg, ptr, end, ®Info->zone, mDNSOpaque16fromIntVal(rr->resrec.rrclass));
// cache zone data
AssignDomainName(&newRR->uDNS_info.zone, &zoneData->zoneName);
- newRR->uDNS_info.ns.type = mDNSAddrType_IPv4;
- newRR->uDNS_info.ns.ip.v4.NotAnInteger = zoneData->primaryAddr.ip.v4.NotAnInteger;
+ newRR->uDNS_info.ns = zoneData->primaryAddr;
if (zoneData->updatePort.NotAnInteger) newRR->uDNS_info.port = zoneData->updatePort;
else
{
rInfo->state = regState_Pending;
SetRecordRetry(m, &srs->RR_SRV, err);
- rInfo->id.NotAnInteger = id.NotAnInteger;
+ rInfo->id = id;
if (mapped) srv->resrec.rdata->u.srv.port = privport;
return;
if (err && err != mStatus_TransientErr) { debugf("ERROR: SendServiceDeregistration - mDNSSendDNSMessage - %ld", err); goto error; }
SetRecordRetry(m, &srs->RR_SRV, err);
- info->id.NotAnInteger = id.NotAnInteger;
+ info->id = id;
info->state = regState_DeregPending;
return;
mDNSexport mStatus uDNS_DeregisterService(mDNS *const m, ServiceRecordSet *srs)
{
- uDNS_GlobalInfo *u = &m->uDNS_info;
NATTraversalInfo *nat = srs->uDNS_info.NATinfo;
- AuthRecord **r = &u->RecordRegistrations;
char *errmsg = "Unknown State";
- // We "silently" unlink any Extras from our RecordRegistration list, as they are implicitly deleted from
- // the server when we delete all RRSets for this name
- while (*r)
- {
- if (SameDomainName(srs->RR_SRV.resrec.name, (*r)->resrec.name)) *r = (*r)->next;
- else r = &(*r)->next;
- }
-
// don't re-register with a new target following deregistration
srs->uDNS_info.SRVChanged = srs->uDNS_info.SRVUpdateDeferred = mDNSfalse;
else
{
err = SetupRecordRegistration(m, &extra->r);
- extra->r.uDNS_info.state = regState_ExtraQueued;
+ extra->r.uDNS_info.state = regState_ExtraQueued; // %%% Is it okay to overwrite the previous uDNS_info.state?
}
if (!err)
mDNSs32 sendtime;
mDNSs32 nextevent = timenow + MIN_UCAST_PERIODIC_EXEC;
DNSMessage msg;
- mStatus err;
+ mStatus err = mStatus_NoError;
mDNSu8 *end;
uDNS_QuestionInfo *info;
else
{
sendtime = q->LastQTime + q->ThisQInterval;
+ if (m->SuppressStdPort53Queries &&
+ sendtime - m->SuppressStdPort53Queries < 0) // Don't allow sendtime to be earlier than SuppressStdPort53Queries
+ sendtime = m->SuppressStdPort53Queries;
if (sendtime - timenow < 0)
{
- mDNSAddr server;
- if (GetServerForName(&m->uDNS_info, &q->qname, &server))
+ DNSServer *server = GetServerForName(&m->uDNS_info, &q->qname);
+ if (server)
{
- err = constructQueryMsg(&msg, &end, q);
+ if (server->teststate == DNSServer_Untested)
+ {
+ InitializeDNSMessage(&msg.h, newMessageID(&m->uDNS_info), uQueryFlags);
+ end = putQuestion(&msg, msg.data, msg.data + AbsoluteMaxDNSMessageData, DNSRelayTestQuestion, kDNSType_PTR, kDNSClass_IN);
+ }
+ else
+ err = constructQueryMsg(&msg, &end, q);
if (err) LogMsg("Error: uDNS_Idle - constructQueryMsg. Skipping question %##s", q->qname.c);
else
{
- err = mDNSSendDNSMessage(m, &msg, end, mDNSInterface_Any, &server, UnicastDNSPort, -1, mDNSNULL);
+ if (server->teststate != DNSServer_Failed)
+ err = mDNSSendDNSMessage(m, &msg, end, mDNSInterface_Any, &server->addr, UnicastDNSPort, -1, mDNSNULL);
+ m->SuppressStdPort53Queries = NonZeroTime(m->timenow + (mDNSPlatformOneSecond+99)/100);
q->LastQTime = timenow;
if (err) debugf("ERROR: uDNS_idle - mDNSSendDNSMessage - %ld", err); // surpress syslog messages if we have no network
else if (q->ThisQInterval < MAX_UCAST_POLL_INTERVAL) q->ThisQInterval = q->ThisQInterval * 2; // don't increase interval if send failed
nexte = CheckNATMappings(m, timenow);
if (nexte - u->nextevent < 0) u->nextevent = nexte;
+ if (m->SuppressStdPort53Queries && m->timenow - m->SuppressStdPort53Queries >= 0)
+ m->SuppressStdPort53Queries = 0; // If suppression time has passed, clear it
+
nexte = CheckQueries(m, timenow);
if (nexte - u->nextevent < 0) u->nextevent = nexte;
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
Change History (most recent first):
* Copyright (c) 2002-2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
Change History (most recent first):
$Log: mDNSMacOSX.c,v $
-Revision 1.308.2.2 2005/08/05 01:12:24 ksekar
-<rdar://problem/4137930> SUTiger: Hostname registration should register IPv6 AAAA record with DNS Update
-<rdar://problem/4147774> SUTiger: Be defensive against invalid UTF-8 in dynamic host names
-<rdar://problem/3923098> SUTiger: Things are showing up with a bogus interface index
-<rdar://problem/4080074> SUTiger: PPP connection disables same-host Bonjour ".local" lookups
+Revision 1.318 2005/10/20 00:10:34 cheshire
+<rdar://problem/4290265> Add check to avoid crashing NAT gateways that have buggy DNS relay code
+
+Revision 1.317 2005/09/24 01:10:26 cheshire
+Fix comment typos
+Revision 1.316 2005/07/29 18:04:22 ksekar
+<rdar://problem/4137930> Hostname registration should register IPv6 AAAA record with DNS Update
-Revision 1.308.2.1 2005/07/22 21:42:59 ksekar
+Revision 1.315 2005/07/22 21:50:55 ksekar
Fix GCC 4.0/Intel compiler warnings
+Revision 1.314 2005/07/11 02:12:09 cheshire
+<rdar://problem/4147774> Be defensive against invalid UTF-8 in dynamic host names
+Fix copy-and-paste error: "CFRelease(StatusVals[0]);" should be "CFRelease(StateVals[0]);"
+
+Revision 1.313 2005/07/04 23:52:25 cheshire
+<rdar://problem/3923098> Things are showing up with a bogus interface index
+
+Revision 1.312 2005/07/04 22:24:36 cheshire
+Export NotifyOfElusiveBug() so other files can call it
+
+Revision 1.311 2005/06/15 13:20:43 cheshire
+<rdar://problem/4147774> Be defensive against invalid UTF-8 in dynamic host names
+
+Revision 1.310 2005/04/07 00:49:58 cheshire
+<rdar://problem/4080074> PPP connection disables Bonjour ".local" lookups
+
+Revision 1.309 2005/03/23 05:53:29 cheshire
+Fix %s where it should have been %##s in debugf & LogMsg calls
+
Revision 1.308 2005/03/09 00:48:44 cheshire
<rdar://problem/4015157> QU packets getting sent too early on wake from sleep
Move "m->p->NetworkChanged = 0;" line from caller to callee
debugf("Requested removal of default registration domain %##s not in contained in list", d->c);
}
-mDNSlocal void NotifyOfElusiveBug(const char *title, mDNSu32 radarid, const char *msg)
+mDNSexport void NotifyOfElusiveBug(const char *title, mDNSu32 radarid, const char *msg)
{
- extern mDNS mDNSStorage;
- NetworkInterfaceInfoOSX *i;
static int notifyCount = 0;
if (notifyCount) return;
// To avoid this, we don't try to display alerts in the first three minutes after boot.
if ((mDNSu32)(mDNSPlatformRawTime()) < (mDNSu32)(mDNSPlatformOneSecond * 180)) return;
- // Determine if we're at Apple (17.*.*.*)
- for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
- if (i->ifinfo.ip.type == mDNSAddrType_IPv4 && i->ifinfo.ip.ip.v4.b[0] == 17)
- break;
- if (!i) return; // If not at Apple, don't show the alert
+ // Unless ForceAlerts is defined, we only show these bug report alerts on machines that have a 17.x.x.x address
+ #if !ForceAlerts
+ {
+ // Determine if we're at Apple (17.*.*.*)
+ extern mDNS mDNSStorage;
+ NetworkInterfaceInfoOSX *i;
+ for (i = mDNSStorage.p->InterfaceList; i; i = i->next)
+ if (i->ifinfo.ip.type == mDNSAddrType_IPv4 && i->ifinfo.ip.ip.v4.b[0] == 17)
+ break;
+ if (!i) return; // If not at Apple, don't show the alert
+ }
+ #endif
// Send a notification to the user to contact coreos-networking
notifyCount++;
dns_config_t *config = v; // use void * to allow compilation on 10.3 systems
mDNS_Lock(m);
p = m->uDNS_info.Servers;
- while (p) { p->flag = -1; p = p->next; } // mark all for deletion
+ while (p) { p->del = mDNStrue; p = p->next; } // mark all for deletion
LogOperation("RegisterSplitDNS: Registering %d resolvers", config->n_resolver);
for (i = 0; i < config->n_resolver; i++)
{
if (r->nameserver[n]->sa_family == AF_INET && !AddrRequiresPPPConnection(r->nameserver[n]))
{
+ // %%% This should use mDNS_AddDNSServer() instead of duplicating functionality here
mDNSAddr saddr;
if (SetupAddr(&saddr, r->nameserver[n])) { LogMsg("RegisterSplitDNS: bad IP address"); continue; }
+ // mDNSAddr saddr = { mDNSAddrType_IPv4, { { { 192, 168, 1, 1 } } } }; // for testing
debugf("Adding dns server from slot %d %d.%d.%d.%d for domain %##s", i, saddr.ip.v4.b[0], saddr.ip.v4.b[1], saddr.ip.v4.b[2], saddr.ip.v4.b[3], d.c);
p = m->uDNS_info.Servers;
while (p)
{
- if (mDNSSameAddress(&p->addr, &saddr) && SameDomainName(&p->domain, &d)) { p->flag = 0; break; }
+ if (mDNSSameAddress(&p->addr, &saddr) && SameDomainName(&p->domain, &d)) { p->del = mDNSfalse; break; }
else p = p->next;
}
if (!p)
{
p = mallocL("DNSServer", sizeof(*p));
if (!p) { LogMsg("Error: malloc"); mDNS_Unlock(m); return mStatus_UnknownErr; }
- p->addr = saddr;
+ p->addr = saddr;
+ p->del = mDNSfalse;
+ p->teststate = DNSServer_Untested;
AssignDomainName(&p->domain, &d);
- p->flag = 0;
p->next = m->uDNS_info.Servers;
m->uDNS_info.Servers = p;
(*nAdditions)++;
DNSServer **s = &m->uDNS_info.Servers;
while (*s)
{
- if ((*s)->flag < 0)
+ if ((*s)->del)
{
p = *s;
*s = (*s)->next;
if (primary)
{
mDNSAddr v4 = zeroAddr, v6 = zeroAddr;
- mDNSBool HavePrimaryGlobalv6 = mDNSfalse; // does the primary interface have a global v6 address?
+ mDNSBool HavePrimaryGlobalv6 = mDNSfalse; // does the primary interface have a global v6 address?
struct ifaddrs *ifa = myGetIfAddrs(1);
if (!CFStringGetCString(primary, buf, 256, kCFStringEncodingUTF8))
Change History (most recent first):
$Log: mDNSMacOSX.h,v $
+Revision 1.51 2005/07/04 22:24:36 cheshire
+Export NotifyOfElusiveBug() so other files can call it
+
Revision 1.50 2005/02/19 00:04:18 cheshire
Add comments
CFRunLoopSourceRef PowerRLS;
};
+extern void NotifyOfElusiveBug(const char *title, mDNSu32 radarid, const char *msg);
extern void mDNSMacOSXNetworkChanged(mDNS *const m);
extern int mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring);
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
Change History (most recent first):
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_LICENSE_HEADER_END@
Change History (most recent first):