summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/mDNSMacOSX/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/mDNSMacOSX/daemon.c')
-rw-r--r--mDNSResponder/mDNSMacOSX/daemon.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/mDNSResponder/mDNSMacOSX/daemon.c b/mDNSResponder/mDNSMacOSX/daemon.c
index 3b3ed393..acdb68fb 100644
--- a/mDNSResponder/mDNSMacOSX/daemon.c
+++ b/mDNSResponder/mDNSMacOSX/daemon.c
@@ -2593,6 +2593,14 @@ mDNSlocal void KQWokenFlushBytes(int fd, __unused short filter, __unused void *c
while (recv(fd, buffer, sizeof(buffer), MSG_DONTWAIT) > 0) continue;
}
+mDNSlocal void SetLowWater(const KQSocketSet *const k, const int r)
+{
+ if (setsockopt(k->sktv4, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
+ LogMsg("SO_RCVLOWAT IPv4 %d error %d errno %d (%s)", k->sktv4, r, errno, strerror(errno));
+ if (setsockopt(k->sktv6, SOL_SOCKET, SO_RCVLOWAT, &r, sizeof(r)) < 0)
+ LogMsg("SO_RCVLOWAT IPv6 %d error %d errno %d (%s)", k->sktv6, r, errno, strerror(errno));
+}
+
mDNSlocal void * KQueueLoop(void *m_param)
{
mDNS *m = m_param;
@@ -2678,6 +2686,13 @@ mDNSlocal void * KQueueLoop(void *m_param)
// 3. The timeout expires
pthread_mutex_unlock(&PlatformStorage.BigMutex);
+ // If we woke up to receive a multicast, set low-water mark to dampen excessive wakeup rate
+ if (m->p->num_mcasts)
+ {
+ SetLowWater(&m->p->permanentsockets, 0x10000);
+ if (ticks > mDNSPlatformOneSecond / 8) ticks = mDNSPlatformOneSecond / 8;
+ }
+
#if USE_SELECT_WITH_KQUEUEFD
struct timeval timeout;
timeout.tv_sec = ticks / mDNSPlatformOneSecond;
@@ -2705,6 +2720,13 @@ mDNSlocal void * KQueueLoop(void *m_param)
// makes the event no longer valid. Now we have the lock, we call kevent again
// and this time we can safely process the events it tells us about.
+ // If we changed UDP socket low-water mark, restore it, so we will be told about every packet
+ if (m->p->num_mcasts)
+ {
+ SetLowWater(&m->p->permanentsockets, 1);
+ m->p->num_mcasts = 0;
+ }
+
static const struct timespec zero_timeout = { 0, 0 };
int events_found;
while ((events_found = kevent(KQueueFD, NULL, 0, new_events, kEventsToReadAtOnce, &zero_timeout)) != 0)