summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSPosix
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-19 08:49:34 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-20 11:23:31 +0200
commite36ca101817ed47e788f1f2801190718736e834e (patch)
treefe04e4574145d3f6359e41690d7685093e762762 /mDNSResponder/mDNSPosix
parentmDNSResponder: Update to v561.1.1 (diff)
downloadrtems-libbsd-e36ca101817ed47e788f1f2801190718736e834e.tar.bz2
mDNSResponder: Update to v567
The sources can be obtained via: https://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-567.tar.gz Update #3522.
Diffstat (limited to 'mDNSResponder/mDNSPosix')
-rwxr-xr-xmDNSResponder/mDNSPosix/Makefile23
-rw-r--r--mDNSResponder/mDNSPosix/NetMonitor.c69
-rwxr-xr-xmDNSResponder/mDNSPosix/mDNSPosix.c40
-rwxr-xr-xmDNSResponder/mDNSPosix/mDNSPosix.h3
4 files changed, 113 insertions, 22 deletions
diff --git a/mDNSResponder/mDNSPosix/Makefile b/mDNSResponder/mDNSPosix/Makefile
index d095a0f4..817a3775 100755
--- a/mDNSResponder/mDNSPosix/Makefile
+++ b/mDNSResponder/mDNSPosix/Makefile
@@ -1,6 +1,6 @@
# -*- tab-width: 4 -*-
#
-# Copyright (c) 2002-2004, Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2002-2004, 2015, Apple Computer, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -30,8 +30,8 @@
# If "make os=xxx" gives lots of errors like "Missing dependency operator",
# then try typing "gmake os=xxx" instead.
#
-# This Makefile builds an mDNSResponder daemon and a libdns_sd.so shared library
-# for Linux. It also builds several example programs for embedded systems.
+# This Makefile builds an mDNSResponder daemon and a libdns_sd.so shared library
+# for Linux. It also builds several example programs for embedded systems.
#
# Make with no arguments to build all production targets.
# 'make DEBUG=1' to build debugging targets.
@@ -57,6 +57,7 @@ JDK = /usr/jdk
CC = @cc
BISON = @bison
FLEX = @flex
+ST = @strip
LD = ld -shared
CP = cp
RM = rm
@@ -71,18 +72,18 @@ JAVACFLAGS_OS = -fPIC -shared -ldns_sd
# Set up diverging paths for debug vs. prod builds
DEBUG=0
ifeq ($(DEBUG),1)
-CFLAGS_DEBUG = -g -DMDNS_DEBUGMSGS=2
+CFLAGS_DEBUG = -g -DMDNS_DEBUGMSGS=2
OBJDIR = objects/debug
BUILDDIR = build/debug
-STRIP = echo
+STRIP = echo
else
# We use -Os for two reasons:
# 1. We want to make small binaries, suitable for putting into hardware devices
# 2. Some of the code analysis warnings only work when some form of optimization is enabled
-CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0
+CFLAGS_DEBUG = -Os -DMDNS_DEBUGMSGS=0
OBJDIR ?= objects/prod
BUILDDIR ?= build/prod
-STRIP = strip -S
+STRIP = $(ST) -S
endif
# Configure per-OS peculiarities
@@ -95,14 +96,14 @@ LD = gcc -shared
LINKOPTS = -lsocket -lnsl -lresolv
JAVACFLAGS_OS += -I$(JDK)/include/solaris
ifneq ($(DEBUG),1)
-STRIP = strip
+STRIP = $(ST)
endif
else
# any target that contains the string "linux"
ifeq ($(findstring linux,$(os)),linux)
CFLAGS_OS = -D_GNU_SOURCE -DHAVE_IPV6 -DNOT_HAVE_SA_LEN -DUSES_NETLINK -DHAVE_LINUX -DTARGET_OS_LINUX -fno-strict-aliasing
-LD = gcc -shared
+LD = $(CC) -shared
FLEXFLAGS_OS = -l
JAVACFLAGS_OS += -I$(JDK)/include/linux
@@ -151,11 +152,11 @@ LD = $(CC) -dynamiclib
LINKOPTS = -lSystem
LDSUFFIX = dylib
JDK = /System/Library/Frameworks/JavaVM.framework/Home
-JAVACFLAGS_OS = -dynamiclib -I/System/Library/Frameworks/JavaVM.framework/Headers -framework JavaVM
+JAVACFLAGS_OS = -dynamiclib -I/System/Library/Frameworks/JavaVM.framework/Headers -framework JavaVM
else
$(error ERROR: Must specify target OS on command-line, e.g. "make os=x [target]".\
-Supported operating systems include: x, linux, linux-uclibc, netbsd, freebsd, openbsd, solaris)
+Supported operating systems include: x, linux, linux-uclibc, netbsd, freebsd, openbsd, solaris)
endif
endif
endif
diff --git a/mDNSResponder/mDNSPosix/NetMonitor.c b/mDNSResponder/mDNSPosix/NetMonitor.c
index 1354f1f8..a3823c54 100644
--- a/mDNSResponder/mDNSPosix/NetMonitor.c
+++ b/mDNSResponder/mDNSPosix/NetMonitor.c
@@ -120,6 +120,7 @@ struct timeval tv_start, tv_end, tv_interval;
static int FilterInterface = 0;
static FilterList *Filters;
#define ExactlyOneFilter (Filters && !Filters->next)
+static mDNSBool AddressType = mDNSAddrType_IPv4;
static int NumPktQ, NumPktL, NumPktR, NumPktB; // Query/Legacy/Response/Bad
static int NumProbes, NumGoodbyes, NumQuestions, NumLegacy, NumAnswers, NumAdditionals;
@@ -464,9 +465,9 @@ mDNSlocal const mDNSu8 *FindUpdate(mDNS *const m, const DNSMessage *const query,
mDNSlocal void DisplayPacketHeader(mDNS *const m, const DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID)
{
- const char *const ptype = (msg->h.flags.b[0] & kDNSFlag0_QR_Response) ? "-R- " :
+ const char *const ptype = (msg->h.flags.b[0] & kDNSFlag0_QR_Response) ? "-R- " :
(srcport.NotAnInteger == MulticastDNSPort.NotAnInteger) ? "-Q- " : "-LQ-";
-
+ const unsigned length = end - (mDNSu8 *)msg;
struct timeval tv;
struct tm tm;
const mDNSu32 index = mDNSPlatformInterfaceIndexfromInterfaceID(m, InterfaceID, mDNSfalse);
@@ -477,7 +478,7 @@ mDNSlocal void DisplayPacketHeader(mDNS *const m, const DNSMessage *const msg, c
mprintf("\n%d:%02d:%02d.%06d Interface %d/%s\n", tm.tm_hour, tm.tm_min, tm.tm_sec, tv.tv_usec, index, if_name);
mprintf("%#-16a %s Q:%3d Ans:%3d Auth:%3d Add:%3d Size:%5d bytes",
- srcaddr, ptype, msg->h.numQuestions, msg->h.numAnswers, msg->h.numAuthorities, msg->h.numAdditionals, end - (mDNSu8 *)msg);
+ srcaddr, ptype, msg->h.numQuestions, msg->h.numAnswers, msg->h.numAuthorities, msg->h.numAdditionals, length);
if (msg->h.id.NotAnInteger) mprintf(" ID:%u", mDNSVal16(msg->h.id));
@@ -488,7 +489,27 @@ mDNSlocal void DisplayPacketHeader(mDNS *const m, const DNSMessage *const msg, c
if (msg->h.flags.b[0] & kDNSFlag0_QR_Response) mprintf(" Truncated");
else mprintf(" Truncated (KA list continues in next packet)");
}
+
mprintf("\n");
+
+ if (length < sizeof(DNSMessageHeader) + NormalMaxDNSMessageData - 192)
+ if (msg->h.flags.b[0] & kDNSFlag0_TC)
+ mprintf("%#-16a **** WARNING: Packet suspiciously small. Payload size (excluding IP and UDP headers)\n"
+ "%#-16a **** should usually be closer to %d bytes before truncation becomes necessary.\n",
+ srcaddr, srcaddr, sizeof(DNSMessageHeader) + NormalMaxDNSMessageData);
+}
+
+mDNSlocal void DisplaySizeCheck(const DNSMessage *const msg, const mDNSu8 *const end, const mDNSAddr *srcaddr, int num_opts)
+{
+ const unsigned length = end - (mDNSu8 *)msg;
+ const int num_records = msg->h.numAnswers + msg->h.numAuthorities + msg->h.numAdditionals - num_opts;
+
+ if (length > sizeof(DNSMessageHeader) + NormalMaxDNSMessageData)
+ if (num_records > 1)
+ mprintf("%#-16a **** ERROR: Oversized packet with %d records.\n"
+ "%#-16a **** Many network devices cannot receive packets larger than %d bytes.\n"
+ "%#-16a **** To minimize interoperability failures, oversized packets MUST be limited to a single resource record.\n",
+ srcaddr, num_records, srcaddr, 40 + 8 + sizeof(DNSMessageHeader) + NormalMaxDNSMessageData, srcaddr);
}
mDNSlocal void DisplayResourceRecord(const mDNSAddr *const srcaddr, const char *const op, const ResourceRecord *const pktrr)
@@ -594,7 +615,7 @@ mDNSlocal void HexDump(const mDNSu8 *ptr, const mDNSu8 *const end)
mDNSlocal void DisplayError(const mDNSAddr *srcaddr, const mDNSu8 *ptr, const mDNSu8 *const end, char *msg)
{
- mprintf("%#-16a **** ERROR: FAILED TO READ %s **** \n", srcaddr, msg);
+ mprintf("%#-16a **** ERROR: FAILED TO READ %s ****\n", srcaddr, msg);
HexDump(ptr, end);
}
@@ -602,6 +623,7 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD
const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID)
{
int i;
+ int num_opts = 0;
const mDNSu8 *ptr = msg->data;
const mDNSu8 *auth = LocateAuthorities(msg, end);
mDNSBool MQ = (srcport.NotAnInteger == MulticastDNSPort.NotAnInteger);
@@ -611,7 +633,7 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD
DisplayPacketHeader(m, msg, end, srcaddr, srcport, dstaddr, InterfaceID);
if (msg->h.id.NotAnInteger != 0xFFFF)
{
- if (MQ) NumPktQ++;else NumPktL++;
+ if (MQ) NumPktQ++; else NumPktL++;
}
for (i=0; i<msg->h.numQuestions; i++)
@@ -648,6 +670,8 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD
ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAns, &pkt);
if (!ptr) { DisplayError(srcaddr, ep, end, "KNOWN ANSWER"); return; }
DisplayResourceRecord(srcaddr, "(KA)", &pkt.r.resrec);
+ if (pkt.r.resrec.rrtype == kDNSType_OPT)
+ { num_opts++; mprintf("%#-16a **** ERROR: OPT RECORD IN ANSWER SECTION ****\n", srcaddr); }
// In the case of queries with long multi-packet KA lists, we count each subsequent KA packet
// the same as a single query, to more accurately reflect the burden on the network
@@ -664,6 +688,8 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD
// After we display an Update record with its matching question (above) we zero out its type and class
// If any remain that haven't been zero'd out, display them here
if (pkt.r.resrec.rrtype || pkt.r.resrec.rrclass) DisplayResourceRecord(srcaddr, "(AU)", &pkt.r.resrec);
+ if (pkt.r.resrec.rrtype == kDNSType_OPT)
+ { num_opts++; mprintf("%#-16a **** ERROR: OPT RECORD IN AUTHORITY SECTION ****\n", srcaddr); }
}
for (i=0; i<msg->h.numAdditionals; i++)
@@ -672,8 +698,15 @@ mDNSlocal void DisplayQuery(mDNS *const m, const DNSMessage *const msg, const mD
ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt);
if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; }
DisplayResourceRecord(srcaddr, pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : "(AD)", &pkt.r.resrec);
+ if (pkt.r.resrec.rrtype == kDNSType_OPT) num_opts++;
}
+ DisplaySizeCheck(msg, end, srcaddr, num_opts);
+
+ // We don't hexdump the DNSMessageHeader here because those six fields (id, flags, numQuestions, numAnswers, numAuthorities, numAdditionals)
+ // have already been swapped to host byte order and displayed, so including them in the hexdump is confusing
+ if (num_opts > 1) { mprintf("%#-16a **** ERROR: MULTIPLE OPT RECORDS ****\n", srcaddr); HexDump(msg->data, end); }
+
if (entry) AnalyseHost(m, entry, InterfaceID);
}
@@ -681,6 +714,7 @@ mDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const
const mDNSAddr *srcaddr, mDNSIPPort srcport, const mDNSAddr *dstaddr, const mDNSInterfaceID InterfaceID)
{
int i;
+ int num_opts = 0;
const mDNSu8 *ptr = msg->data;
HostEntry *entry = GotPacketFromHost(srcaddr, HostPkt_R, msg->h.id);
LargeCacheRecord pkt;
@@ -718,6 +752,8 @@ mDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const
DisplayResourceRecord(srcaddr, "(DE)", &pkt.r.resrec);
recordstat(entry, pkt.r.resrec.name, OP_goodbye, pkt.r.resrec.rrtype);
}
+ if (pkt.r.resrec.rrtype == kDNSType_OPT)
+ { num_opts++; mprintf("%#-16a **** ERROR: OPT RECORD IN ANSWER SECTION ****\n", srcaddr); }
}
for (i=0; i<msg->h.numAuthorities; i++)
@@ -725,9 +761,12 @@ mDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const
const mDNSu8 *ep = ptr;
ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAuth, &pkt);
if (!ptr) { DisplayError(srcaddr, ep, end, "AUTHORITY"); return; }
- if (pkt.r.resrec.rrtype != kDNSType_NSEC3)
+ DisplayResourceRecord(srcaddr, "(AU)", &pkt.r.resrec);
+ if (pkt.r.resrec.rrtype == kDNSType_OPT)
+ { num_opts++; mprintf("%#-16a **** ERROR: OPT RECORD IN AUTHORITY SECTION ****\n", srcaddr); }
+ else if (pkt.r.resrec.rrtype != kDNSType_NSEC3)
mprintf("%#-16a (?) **** ERROR: SHOULD NOT HAVE AUTHORITY IN mDNS RESPONSE **** %-5s %##s\n",
- srcaddr, DNSTypeName(pkt.r.resrec.rrtype), pkt.r.resrec.name->c);
+ srcaddr, DNSTypeName(pkt.r.resrec.rrtype), pkt.r.resrec.name->c);
}
for (i=0; i<msg->h.numAdditionals; i++)
@@ -736,12 +775,19 @@ mDNSlocal void DisplayResponse(mDNS *const m, const DNSMessage *const msg, const
ptr = GetLargeResourceRecord(m, msg, ptr, end, InterfaceID, kDNSRecordTypePacketAdd, &pkt);
if (!ptr) { DisplayError(srcaddr, ep, end, "ADDITIONAL"); return; }
NumAdditionals++;
+ if (pkt.r.resrec.rrtype == kDNSType_OPT) num_opts++;
DisplayResourceRecord(srcaddr,
pkt.r.resrec.rrtype == kDNSType_OPT ? "(OP)" : (pkt.r.resrec.RecordType & kDNSRecordTypePacketUniqueMask) ? "(AD)" : "(AD+)",
&pkt.r.resrec);
if (entry) RecordHostInfo(entry, &pkt.r.resrec);
}
+ DisplaySizeCheck(msg, end, srcaddr, num_opts);
+
+ // We don't hexdump the DNSMessageHeader here because those six fields (id, flags, numQuestions, numAnswers, numAuthorities, numAdditionals)
+ // have already been swapped to host byte order and displayed, so including them in the hexdump is confusing
+ if (num_opts > 1) { mprintf("%#-16a **** ERROR: MULTIPLE OPT RECORDS ****\n", srcaddr); HexDump(msg->data, end); }
+
if (entry) AnalyseHost(m, entry, InterfaceID);
}
@@ -763,7 +809,7 @@ mDNSlocal void ProcessUnicastResponse(mDNS *const m, const DNSMessage *const msg
mDNSlocal mDNSBool AddressMatchesFilterList(const mDNSAddr *srcaddr)
{
FilterList *f;
- if (!Filters) return(srcaddr->type == mDNSAddrType_IPv4);
+ if (!Filters) return(srcaddr->type == AddressType);
for (f=Filters; f; f=f->next) if (mDNSSameAddress(srcaddr, &f->FilterAddr)) return(mDNStrue);
return(mDNSfalse);
}
@@ -930,9 +976,14 @@ mDNSexport int main(int argc, char **argv)
if (i+1 < argc && !strcmp(argv[i], "-i") && atoi(argv[i+1]))
{
FilterInterface = atoi(argv[i+1]);
- i += 2;
+ i += 1;
printf("Monitoring interface %d\n", FilterInterface);
}
+ else if (!strcmp(argv[i], "-6"))
+ {
+ AddressType = mDNSAddrType_IPv6;
+ printf("Monitoring IPv6 traffic\n");
+ }
else
{
struct in_addr s4;
diff --git a/mDNSResponder/mDNSPosix/mDNSPosix.c b/mDNSResponder/mDNSPosix/mDNSPosix.c
index 6bc22af3..bdfb71f2 100755
--- a/mDNSResponder/mDNSPosix/mDNSPosix.c
+++ b/mDNSResponder/mDNSPosix/mDNSPosix.c
@@ -90,6 +90,8 @@ static GenLinkedList gEventSources; // linked list of PosixEventSour
static sigset_t gEventSignalSet; // Signals which event loop listens for
static sigset_t gEventSignals; // Signals which were received while inside loop
+static PosixNetworkInterface *gRecentInterfaces;
+
// ***************************************************************************
// Globals (for debugging)
@@ -574,6 +576,13 @@ mDNSexport mDNSu32 mDNSPlatformInterfaceIndexfromInterfaceID(mDNS *const m, mDNS
while ((intf != NULL) && (mDNSInterfaceID) intf != id)
intf = (PosixNetworkInterface *)(intf->coreIntf.next);
+ if (intf) return intf->index;
+
+ // If we didn't find the interface, check the RecentInterfaces list as well
+ intf = gRecentInterfaces;
+ while ((intf != NULL) && (mDNSInterfaceID) intf != id)
+ intf = (PosixNetworkInterface *)(intf->coreIntf.next);
+
return intf ? intf->index : 0;
}
@@ -587,7 +596,11 @@ mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
#if HAVE_IPV6
if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0);
#endif
- free(intf);
+
+ // Move interface to the RecentInterfaces list for a minute
+ intf->LastSeen = mDNSPlatformUTC();
+ intf->coreIntf.next = &gRecentInterfaces->coreIntf;
+ gRecentInterfaces = intf;
}
// Grab the first interface, deregister it, free it, and repeat until done.
@@ -643,6 +656,14 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
#error This platform has no way to avoid address busy errors on multicast.
#endif
if (err < 0) { err = errno; perror("setsockopt - SO_REUSExxxx"); }
+
+ // Enable inbound packets on IFEF_AWDL interface.
+ // Only done for multicast sockets, since we don't expect unicast socket operations
+ // on the IFEF_AWDL interface. Operation is a no-op for other interface types.
+ #ifndef SO_RECV_ANYIF
+ #define SO_RECV_ANYIF 0x1104 /* unrestricted inbound processing */
+ #endif
+ if (setsockopt(*sktPtr, SOL_SOCKET, SO_RECV_ANYIF, &kOn, sizeof(kOn)) < 0) perror("setsockopt - SO_RECV_ANYIF");
}
// We want to receive destination addresses and interface identifiers.
@@ -978,6 +999,17 @@ mDNSlocal int SetupInterfaceList(mDNS *const m)
// Clean up.
if (intfList != NULL) free_ifi_info(intfList);
+
+ // Clean up any interfaces that have been hanging around on the RecentInterfaces list for more than a minute
+ PosixNetworkInterface **ri = &gRecentInterfaces;
+ const mDNSs32 utc = mDNSPlatformUTC();
+ while (*ri)
+ {
+ PosixNetworkInterface *pi = *ri;
+ if (utc - pi->LastSeen < 60) ri = (PosixNetworkInterface **)&pi->coreIntf.next;
+ else { *ri = (PosixNetworkInterface *)pi->coreIntf.next; free(pi); }
+ }
+
return err;
}
@@ -1318,9 +1350,15 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
#endif
}
+// This is used internally by InterfaceChangeCallback.
+// It's also exported so that the Standalone Responder (mDNSResponderPosix)
+// can call it in response to a SIGHUP (mainly for debugging purposes).
mDNSexport mStatus mDNSPlatformPosixRefreshInterfaceList(mDNS *const m)
{
int err;
+ // This is a pretty heavyweight way to process interface changes --
+ // destroying the entire interface list and then making fresh one from scratch.
+ // We should make it like the OS X version, which leaves unchanged interfaces alone.
ClearInterfaceList(m);
err = SetupInterfaceList(m);
return PosixErrorToStatus(err);
diff --git a/mDNSResponder/mDNSPosix/mDNSPosix.h b/mDNSResponder/mDNSPosix/mDNSPosix.h
index f6dab9e9..9e16bb89 100755
--- a/mDNSResponder/mDNSPosix/mDNSPosix.h
+++ b/mDNSResponder/mDNSPosix/mDNSPosix.h
@@ -38,7 +38,8 @@ typedef struct PosixNetworkInterface PosixNetworkInterface;
struct PosixNetworkInterface
{
- NetworkInterfaceInfo coreIntf;
+ NetworkInterfaceInfo coreIntf; // MUST be the first element in this structure
+ mDNSs32 LastSeen;
const char * intfName;
PosixNetworkInterface * aliasIntf;
int index;