summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSPosix/mDNSPosix.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSPosix/mDNSPosix.c')
-rwxr-xr-xmDNSResponder/mDNSPosix/mDNSPosix.c40
1 files changed, 39 insertions, 1 deletions
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);