From: Remi Gacogne Date: Fri, 28 Jul 2017 14:14:39 +0000 (+0200) Subject: dnsdist: Use `accept4()` to set the socket non-blocking, when available X-Git-Tag: rec-4.1.0-rc1~22^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0c8d25a713d462412f7749043945501cb08d67d4;p=pdns dnsdist: Use `accept4()` to set the socket non-blocking, when available --- diff --git a/m4/pdns_check_network_libs.m4 b/m4/pdns_check_network_libs.m4 index 36169bbae..d8b020c87 100644 --- a/m4/pdns_check_network_libs.m4 +++ b/m4/pdns_check_network_libs.m4 @@ -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]) ]) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 4e3e1071a..6ab24b46c 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -256,9 +256,6 @@ void* tcpClientThread(int pipefd) time_t connectionStartTime = time(NULL); std::vector 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;