lots of useless recvfrom() calls

Lennert Buytenhek buytenh at wantstofly.org
Fri May 4 19:05:03 MSK 2018


Hi!

I am using the patch below to avoid one useless recvfrom() call (that
returns EAGAIN) for every call to dns_ioevent().  Under low load, where
every call to dns_ioevent() processes one DNS reply, this saves half of
the total number of recvfrom() calls.

Since I use level-triggered event notification, it's fine if
dns_ioevent() doesn't process all packets pending for this dns_ctx,
because if the fd is still active when dns_ioevent() returns, it
will be called again at some point.

Also, looping until EAGAIN makes your application somewhat susceptible
to being DoSed.  (The event polling framework I use spends a lot of
effort to make sure that all event sources are handled fairly, and that
no one event source can starve out processing of other event sources.)

If udns should work with edge-triggered event notification frameworks,
then perhaps we could add a new function, say, dns_ioevent_single(),
that only processes a single packet for this dns_ctx, and then have
dns_ioevent() just call the _single() version in a loop until EAGAIN,
or something like that?



diff -up ./udns_resolver.c.orig ./udns_resolver.c
--- ./udns_resolver.c.orig	2018-05-04 15:52:58.368856384 +0300
+++ ./udns_resolver.c	2018-05-04 16:11:48.159375836 +0300
@@ -976,7 +976,6 @@ void dns_ioevent(struct dns_ctx *ctx, ti
 
   if (!now) now = time(NULL);
 
-again: /* receive the reply */
 
   slen = sizeof(sns);
   r = recvfrom(ctx->dnsc_udpsock, (void*)pbuf, ctx->dnsc_udpbuf,
@@ -1197,6 +1196,8 @@ again: /* receive the reply */
   }
   goto again;
 
+again: /* receive the reply */
+  dns_request_utm(ctx, now);
 }
 
 /* handle all timeouts */


More information about the udns mailing list