]> granicus.if.org Git - pdns/commitdiff
dnsdist: Use `accept4()` to set the socket non-blocking, when available
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 28 Jul 2017 14:14:39 +0000 (16:14 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 5 Sep 2017 14:52:23 +0000 (16:52 +0200)
m4/pdns_check_network_libs.m4
pdns/dnsdist-tcp.cc

index 36169bbae58922edf96bce3543622434613bc698..d8b020c875ff882efa154692a8bdee41f9a585f6 100644 (file)
@@ -3,5 +3,5 @@ AC_DEFUN([PDNS_CHECK_NETWORK_LIBS],[
   AC_SEARCH_LIBS([gethostbyname], [nsl])
   AC_SEARCH_LIBS([socket], [socket])
   AC_SEARCH_LIBS([gethostent], [nsl])
-  AC_CHECK_FUNCS([recvmmsg sendmmsg])
+  AC_CHECK_FUNCS([recvmmsg sendmmsg accept4])
 ])
index 4e3e1071af169b1319e00f8ddc7601be385e116e..6ab24b46c595c7407d26045dcc6398a6b1f46f10 100644 (file)
@@ -256,9 +256,6 @@ void* tcpClientThread(int pipefd)
     time_t connectionStartTime = time(NULL);
     std::vector<char> queryBuffer;
 
-    if (!setNonBlocking(ci.fd))
-      goto drop;
-
     if (getsockname(ci.fd, (sockaddr*)&dest, &len)) {
       dest = ci.cs->local;
     }
@@ -627,10 +624,18 @@ void* tcpAcceptorThread(void* p)
     ConnectionInfo* ci = nullptr;
     tcpClientCountIncremented = false;
     try {
+      socklen_t remlen = remote.getSocklen();
       ci = new ConnectionInfo;
       ci->cs = cs;
       ci->fd = -1;
-      ci->fd = SAccept(cs->tcpFD, remote);
+#ifdef HAVE_ACCEPT4
+      ci->fd = accept4(cs->tcpFD, (struct sockaddr*)&remote, &remlen, SOCK_NONBLOCK);
+#else
+      ci->fd = accept(cs->tcpFD, (struct sockaddr*)&remote, &remlen);
+#endif
+      if(ci->fd < 0) {
+        throw std::runtime_error((boost::format("accepting new connection on socket: %s") % strerror(errno)).str());
+      }
 
       if(!acl->match(remote)) {
        g_stats.aclDrops++;
@@ -641,6 +646,15 @@ void* tcpAcceptorThread(void* p)
        continue;
       }
 
+#ifndef HAVE_ACCEPT4
+      if (!setNonBlocking(ci->fd)) {
+        close(ci->fd);
+        delete ci;
+        ci=nullptr;
+        continue;
+      }
+#endif
+
       if(g_maxTCPQueuedConnections > 0 && g_tcpclientthreads->getQueuedCount() >= g_maxTCPQueuedConnections) {
         close(ci->fd);
         delete ci;