mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
DNS_Mgr: Replace ares_fds() with ares_getsock()
On Slack, a user reported "fortify source" aborts within ares_fds() due to the FDs used by c-ares exceeding 1024 and thereby larger than the maximum fd value that a fd_set can hold. Switch to ares_get_socks() and poll() to avoid this. Closes #3309.
This commit is contained in:
parent
03597d210d
commit
c4c4a23bfd
1 changed files with 48 additions and 12 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -992,23 +992,54 @@ void DNS_Mgr::Resolve()
|
|||
{
|
||||
int nfds = 0;
|
||||
struct timeval *tvp, tv;
|
||||
fd_set read_fds, write_fds;
|
||||
struct pollfd pollfds[ARES_GETSOCK_MAXNUM];
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
|
||||
tv.tv_sec = DNS_TIMEOUT;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
for ( int i = 0; i < MAX_PENDING_REQUESTS; i++ )
|
||||
{
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
nfds = ares_fds(channel, &read_fds, &write_fds);
|
||||
int nfds = 0;
|
||||
int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);
|
||||
|
||||
for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ )
|
||||
{
|
||||
bool rd = ARES_GETSOCK_READABLE(bitmap, i);
|
||||
bool wr = ARES_GETSOCK_WRITABLE(bitmap, i);
|
||||
if ( rd || wr )
|
||||
{
|
||||
pollfds[nfds].fd = socks[i];
|
||||
pollfds[nfds].events = rd ? POLLIN : 0;
|
||||
pollfds[nfds].events |= wr ? POLLOUT : 0;
|
||||
++nfds;
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have any sockets that are read or writable?
|
||||
if ( nfds == 0 )
|
||||
break;
|
||||
|
||||
// poll() timeout is in milliseconds.
|
||||
tvp = ares_timeout(channel, &tv, &tv);
|
||||
int res = select(nfds, &read_fds, &write_fds, NULL, tvp);
|
||||
if ( res >= 0 )
|
||||
ares_process(channel, &read_fds, &write_fds);
|
||||
int timeout_ms = tvp->tv_sec * 1000 + tvp->tv_usec / 1000;
|
||||
|
||||
int res = poll(pollfds, nfds, timeout_ms);
|
||||
|
||||
if ( res > 0 )
|
||||
{
|
||||
for ( int i = 0; i < nfds; i++ )
|
||||
{
|
||||
int rdfd = pollfds[i].revents | POLLIN ? pollfds[i].fd : ARES_SOCKET_BAD;
|
||||
int wrfd = pollfds[i].revents | POLLOUT ? pollfds[i].fd : ARES_SOCKET_BAD;
|
||||
|
||||
if ( rdfd != ARES_SOCKET_BAD || wrfd != ARES_SOCKET_BAD )
|
||||
ares_process_fd(channel, rdfd, wrfd);
|
||||
}
|
||||
}
|
||||
else if ( res == 0 )
|
||||
// Do timeout processing when poll() timed out.
|
||||
ares_process_fd(channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1442,11 +1473,16 @@ double DNS_Mgr::GetNextTimeout()
|
|||
if ( asyncs_pending == 0 )
|
||||
return -1;
|
||||
|
||||
fd_set read_fds, write_fds;
|
||||
int nfds = 0;
|
||||
ares_socket_t socks[ARES_GETSOCK_MAXNUM];
|
||||
int bitmap = ares_getsock(channel, socks, ARES_GETSOCK_MAXNUM);
|
||||
for ( int i = 0; i < ARES_GETSOCK_MAXNUM; i++ )
|
||||
{
|
||||
if ( ARES_GETSOCK_READABLE(bitmap, i) || ARES_GETSOCK_WRITABLE(bitmap, i) )
|
||||
++nfds;
|
||||
}
|
||||
|
||||
FD_ZERO(&read_fds);
|
||||
FD_ZERO(&write_fds);
|
||||
int nfds = ares_fds(channel, &read_fds, &write_fds);
|
||||
// Do we have any sockets that are read or writable?
|
||||
if ( nfds == 0 )
|
||||
return -1;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue