diff options
Diffstat (limited to 'ares/ares_process.c')
-rw-r--r-- | ares/ares_process.c | 92 |
1 files changed, 76 insertions, 16 deletions
diff --git a/ares/ares_process.c b/ares/ares_process.c index 8cb51c3b2..efc462a40 100644 --- a/ares/ares_process.c +++ b/ares/ares_process.c @@ -56,10 +56,11 @@ static int try_again(int errnum); static void write_tcp_data(ares_channel channel, fd_set *write_fds, - time_t now); -static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now); + ares_socket_t write_fd, time_t now); +static void read_tcp_data(ares_channel channel, fd_set *read_fds, + ares_socket_t read_fd, time_t now); static void read_udp_packets(ares_channel channel, fd_set *read_fds, - time_t now); + ares_socket_t read_fd, time_t now); static void process_timeouts(ares_channel channel, time_t now); static void process_answer(ares_channel channel, unsigned char *abuf, int alen, int whichserver, int tcp, int now); @@ -80,12 +81,30 @@ void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds) time_t now; time(&now); - write_tcp_data(channel, write_fds, now); - read_tcp_data(channel, read_fds, now); - read_udp_packets(channel, read_fds, now); + write_tcp_data(channel, write_fds, ARES_SOCKET_BAD, now); + read_tcp_data(channel, read_fds, ARES_SOCKET_BAD, now); + read_udp_packets(channel, read_fds, ARES_SOCKET_BAD, now); process_timeouts(channel, now); } +/* Something interesting happened on the wire, or there was a timeout. + * See what's up and respond accordingly. + */ +void ares_process_fd(ares_channel channel, + ares_socket_t read_fd, /* use ARES_SOCKET_BAD or valid + file descriptors */ + ares_socket_t write_fd) +{ + time_t now; + + time(&now); + write_tcp_data(channel, NULL, write_fd, now); + read_tcp_data(channel, NULL, read_fd, now); + read_udp_packets(channel, NULL, read_fd, now); + process_timeouts(channel, now); +} + + /* Return 1 if the specified error number describes a readiness error, or 0 * otherwise. This is mostly for HP-UX, which could return EAGAIN or * EWOULDBLOCK. See this man page @@ -114,7 +133,10 @@ static int try_again(int errnum) /* If any TCP sockets select true for writing, write out queued data * we have for them. */ -static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) +static void write_tcp_data(ares_channel channel, + fd_set *write_fds, + ares_socket_t write_fd, + time_t now) { struct server_state *server; struct send_request *sendreq; @@ -124,14 +146,27 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) ssize_t wcount; size_t n; + if(!write_fds && (write_fd == ARES_SOCKET_BAD)) + /* no possible action */ + return; + for (i = 0; i < channel->nservers; i++) { - /* Make sure server has data to send and is selected in write_fds. */ + /* Make sure server has data to send and is selected in write_fds or + write_fd. */ server = &channel->servers[i]; - if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD - || !FD_ISSET(server->tcp_socket, write_fds)) + if (!server->qhead || server->tcp_socket == ARES_SOCKET_BAD) continue; + if(write_fds) { + if(!FD_ISSET(server->tcp_socket, write_fds)) + continue; + } + else { + if(server->tcp_socket != write_fd) + continue; + } + /* Count the number of send queue items. */ n = 0; for (sendreq = server->qhead; sendreq; sendreq = sendreq->next) @@ -218,20 +253,33 @@ static void write_tcp_data(ares_channel channel, fd_set *write_fds, time_t now) * allocate a buffer if we finish reading the length word, and process * a packet if we finish reading one. */ -static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) +static void read_tcp_data(ares_channel channel, fd_set *read_fds, + ares_socket_t read_fd, time_t now) { struct server_state *server; int i; ssize_t count; + if(!read_fds && (read_fd == ARES_SOCKET_BAD)) + /* no possible action */ + return; + for (i = 0; i < channel->nservers; i++) { /* Make sure the server has a socket and is selected in read_fds. */ server = &channel->servers[i]; - if (server->tcp_socket == ARES_SOCKET_BAD || - !FD_ISSET(server->tcp_socket, read_fds)) + if (server->tcp_socket == ARES_SOCKET_BAD) continue; + if(read_fds) { + if(!FD_ISSET(server->tcp_socket, read_fds)) + continue; + } + else { + if(server->tcp_socket != read_fd) + continue; + } + if (server->tcp_lenbuf_pos != 2) { /* We haven't yet read a length word, so read that (or @@ -294,22 +342,34 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, time_t now) /* If any UDP sockets select true for reading, process them. */ static void read_udp_packets(ares_channel channel, fd_set *read_fds, - time_t now) + ares_socket_t read_fd, time_t now) { struct server_state *server; int i; ssize_t count; unsigned char buf[PACKETSZ + 1]; + if(!read_fds && (read_fd == ARES_SOCKET_BAD)) + /* no possible action */ + return; + for (i = 0; i < channel->nservers; i++) { /* Make sure the server has a socket and is selected in read_fds. */ server = &channel->servers[i]; - if (server->udp_socket == ARES_SOCKET_BAD || - !FD_ISSET(server->udp_socket, read_fds)) + if (server->udp_socket == ARES_SOCKET_BAD) continue; + if(read_fds) { + if(!FD_ISSET(server->udp_socket, read_fds)) + continue; + } + else { + if(server->udp_socket != read_fd) + continue; + } + count = sread(server->udp_socket, buf, sizeof(buf)); if (count == -1 && try_again(SOCKERRNO)) continue; |