#include "CryptoAlg.h"
#include "anonymous.h"
+#ifdef UNIT_TEST
+#include "unittest.h"
+#endif
+
// Disable certain benign warnings with Microsoft compilers
#if (defined(_MSC_VER))
// Disable "conditional expression is constant" warning for debug macros.
mDNSexport const mDNSOpaque16 SubscribeFlags = { { kDNSFlag0_QR_Query | kDNSFlag0_OP_Subscribe, 0 } };
mDNSexport const mDNSOpaque16 UnSubscribeFlags= { { kDNSFlag0_QR_Query | kDNSFlag0_OP_UnSubscribe, 0 } };
-mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque64 zeroOpaque64 = { { 0 } };
+mDNSexport const mDNSOpaque128 zeroOpaque128 = { { 0 } };
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
#pragma mark - Domain Name Utility Functions
#endif
+#if !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainLabel(const mDNSu8 *a, const mDNSu8 *b)
{
int i;
return(mDNStrue);
}
+#endif // !APPLE_OSX_mDNSResponder
+
mDNSexport mDNSBool SameDomainName(const domainname *const d1, const domainname *const d2)
{
const mDNSu8 * a = d1->c;
hostlabel->c[0] = (mDNSu8)(ptr - &hostlabel->c[1]);
}
-#define ValidTransportProtocol(X) ( (X)[0] == 4 && (X)[1] == '_' && \
- ((((X)[2] | 0x20) == 'u' && ((X)[3] | 0x20) == 'd') || (((X)[2] | 0x20) == 't' && ((X)[3] | 0x20) == 'c')) && \
- ((X)[4] | 0x20) == 'p')
-
mDNSexport mDNSu8 *ConstructServiceName(domainname *const fqdn,
const domainlabel *name, const domainname *type, const domainname *const domain)
{
{
LogMsg("Bad service type in %#s.%##s%##s Application protocol name must be underscore plus 1-15 characters. "
"See <http://www.dns-sd.org/ServiceTypes.html>", name->c, type->c, domain->c);
-#if APPLE_OSX_mDNSResponder
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameTooLong", "noop", typeBuf, "");
-#endif
}
if (len < 2 || len >= 0x40 || (len > 16 && !SameDomainName(domain, &localdomain))) return(mDNSNULL);
if (src[1] != '_') { errormsg = "Application protocol name must begin with underscore"; goto fail; }
if (src[i] == '_' && loggedUnderscore == mDNSfalse)
{
ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithUnderscore", "noop", typeBuf, "");
+ LogInfo("ConstructServiceName: Service type with non-leading underscore %s", typeBuf);
loggedUnderscore = mDNStrue;
}
#endif
continue;
}
errormsg = "Application protocol name must contain only letters, digits, and hyphens";
-#if APPLE_OSX_mDNSResponder
- {
- ConvertDomainNameToCString(type, typeBuf);
- mDNSASLLog(mDNSNULL, "serviceType.nameWithIllegalCharacters", "noop", typeBuf, "");
- }
-#endif
goto fail;
}
for (i=0; i<=len; i++) *dst++ = *src++;
while (1) // Read sequence of labels
{
+ int i;
+ mDNSu16 offset;
const mDNSu8 len = *ptr++; // Read length of this label
if (len == 0) break; // If length is zero, that means this name is complete
switch (len & 0xC0)
{
- int i;
- mDNSu16 offset;
case 0x00: if (ptr + len >= end) // Remember: expect at least one more byte for the root label
{ debugf("getDomainName: Malformed domain name (overruns packet end)"); return(mDNSNULL); }
case 0x80: debugf("getDomainName: Illegal label length 0x%X in domain name %##s", len, name->c); return(mDNSNULL);
- case 0xC0: offset = (mDNSu16)((((mDNSu16)(len & 0x3F)) << 8) | *ptr++);
+ case 0xC0: if (ptr >= end)
+ { debugf("getDomainName: Malformed compression label (overruns packet end)"); return(mDNSNULL); }
+ offset = (mDNSu16)((((mDNSu16)(len & 0x3F)) << 8) | *ptr++);
if (!nextbyte) nextbyte = ptr; // Record where we got to before we started following pointers
ptr = (mDNSu8 *)msg + offset;
if (ptr < (mDNSu8*)msg || ptr >= end)
AssignDomainName(&name, (domainname *)ptr);
ptr += DomainNameLength(&name);
}
- if (!ptr)
+ if (!ptr || ptr >= end)
{
LogInfo("SetRData: Malformed name for TSIG/TKEY type %d", rr->resrec.rrtype);
goto fail;
rr->CRActiveQuestion = mDNSNULL;
rr->UnansweredQueries = 0;
rr->LastUnansweredTime= 0;
-#if ENABLE_MULTI_PACKET_QUERY_SNOOPING
- rr->MPUnansweredQ = 0;
- rr->MPLastUnansweredQT= 0;
- rr->MPUnansweredKA = 0;
- rr->MPExpectingKA = mDNSfalse;
-#endif
rr->NextInCFList = mDNSNULL;
rr->resrec.InterfaceID = InterfaceID;
pktrdlength = (mDNSu16)((mDNSu16)ptr[8] << 8 | ptr[9]);
// If mDNS record has cache-flush bit set, we mark it unique
- // For uDNS records, all are implicitly deemed unique (a single DNS server is always
- // authoritative for the entire RRSet), unless this is a truncated response
- if (ptr[2] & (kDNSClass_UniqueRRSet >> 8) || (!InterfaceID && !(msg->h.flags.b[0] & kDNSFlag0_TC)))
+ // For uDNS records, all are implicitly deemed unique (a single DNS server is always authoritative for the entire RRSet)
+ if (ptr[2] & (kDNSClass_UniqueRRSet >> 8) || !InterfaceID)
RecordType |= kDNSRecordTypePacketUniqueMask;
ptr += 10;
if (ptr + pktrdlength > end) { debugf("GetLargeResourceRecord: RDATA exceeds end of packet"); return(mDNSNULL); }
}
// Get the lease life of records in a dynamic update
-// returns 0 on error or if no lease present
-mDNSexport mDNSu32 GetPktLease(mDNS *m, DNSMessage *msg, const mDNSu8 *end)
+mDNSexport mDNSBool GetPktLease(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, mDNSu32 *const lease)
{
- mDNSu32 result = 0;
const mDNSu8 *ptr = LocateOptRR(msg, end, DNSOpt_LeaseData_Space);
- if (ptr) ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
- if (ptr && m->rec.r.resrec.rdlength >= DNSOpt_LeaseData_Space && m->rec.r.resrec.rdata->u.opt[0].opt == kDNSOpt_Lease)
- result = m->rec.r.resrec.rdata->u.opt[0].u.updatelease;
- m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
- return(result);
+ if (ptr)
+ {
+ ptr = GetLargeResourceRecord(m, msg, ptr, end, 0, kDNSRecordTypePacketAdd, &m->rec);
+ if (ptr && m->rec.r.resrec.RecordType != kDNSRecordTypePacketNegative && m->rec.r.resrec.rrtype == kDNSType_OPT)
+ {
+ const rdataOPT *o;
+ const rdataOPT *const e = (const rdataOPT *)&m->rec.r.resrec.rdata->u.data[m->rec.r.resrec.rdlength];
+ for (o = &m->rec.r.resrec.rdata->u.opt[0]; o < e; o++)
+ if (o->opt == kDNSOpt_Lease)
+ {
+ *lease = o->u.updatelease;
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ return mDNStrue;
+ }
+ }
+ m->rec.r.resrec.RecordType = 0; // Clear RecordType to show we're not still using it
+ }
+ return mDNSfalse;
}
mDNSlocal const mDNSu8 *DumpRecords(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *ptr, const mDNSu8 *const end, int count, char *label)
#pragma mark - Packet Sending Functions
#endif
+#ifdef UNIT_TEST
+// Run the unit test of mDNSSendDNSMessage
+UNITTEST_SENDDNSMESSAGE
+#else
// Stub definition of TCPSocket_struct so we can access flags field. (Rest of TCPSocket_struct is platform-dependent.)
struct TCPSocket_struct { TCPSocketFlags flags; /* ... */ };
// Stub definition of UDPSocket_struct so we can access port field. (Rest of UDPSocket_struct is platform-dependent.)
return(status);
}
+#endif // UNIT_TEST
// ***************************************************************************
#if COMPILER_LIKES_PRAGMA_MARK
mDNSlocal mDNSs32 GetNextScheduledEvent(const mDNS *const m)
{
- mDNSs32 e = m->timenow + 0x78000000;
+ mDNSs32 e = m->timenow + FutureTime;
if (m->mDNSPlatformStatus != mStatus_NoError) return(e);
if (m->NewQuestions)
{
for (c = *fmt; c != 0; c = *++fmt)
{
- if (c != '%')
+ unsigned long n;
+ if (c != '%')
{
*sbuffer++ = (char)c;
if (++nwritten >= buflen) goto exit;
conv:
switch (c) // perform appropriate conversion
{
- unsigned long n;
case 'h': F.hSize = 1; c = *++fmt; goto conv;
case 'l': // fall through
case 'L': F.lSize = 1; c = *++fmt; goto conv;