Added ares_getsock() to extract sockets to wait for action on, without being
authorDaniel Stenberg <daniel@haxx.se>
Thu, 22 Dec 2005 15:27:41 +0000 (15:27 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 22 Dec 2005 15:27:41 +0000 (15:27 +0000)
limited to select().

Makefile.inc
ares.h
ares_getsock.3 [new file with mode: 0644]
ares_getsock.c [new file with mode: 0644]

index f8d9058..c90aae4 100644 (file)
@@ -1,11 +1,11 @@
-CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c       \
-ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c  \
-ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c     \
-ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c     \
-ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c       \
-windows_port.c ares_expand_string.c ares_parse_ptr_reply.c                  \
-ares_parse_aaaa_reply.c ares_getnameinfo.c inet_net_pton.c bitncmp.c        \
-inet_ntop.c
+CSOURCES = ares_fds.c ares_getsock.c ares_process.c ares_free_hostent.c        \
+ares_query.c ares__close_sockets.c ares_free_string.c ares_search.c    \
+ares__get_hostent.c ares_gethostbyaddr.c ares_send.c ares__read_line.c \
+ares_gethostbyname.c ares_strerror.c ares_cancel.c ares_init.c         \
+ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c            \
+ares_expand_name.c ares_parse_a_reply.c windows_port.c                 \
+ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c    \
+ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c
 
 HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h          \
            nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h
diff --git a/ares.h b/ares.h
index 7f76112..8e8da28 100644 (file)
--- a/ares.h
+++ b/ares.h
@@ -70,8 +70,8 @@ extern "C" {
 #define ARES_EBADFLAGS          18
 
 /* ares_getaddrinfo error codes */
-#define ARES_ENONAME           19
-#define ARES_EBADHINTS         20
+#define ARES_ENONAME            19
+#define ARES_EBADHINTS          20
 
 /* Flag values */
 #define ARES_FLAG_USEVC         (1 << 0)
@@ -108,27 +108,32 @@ extern "C" {
 #define ARES_NI_LOOKUPHOST              (1 << 8)
 #define ARES_NI_LOOKUPSERVICE           (1 << 9)
 /* Reserved for future use */
-#define ARES_NI_IDN                    (1 << 10)
-#define ARES_NI_IDN_ALLOW_UNASSIGNED   (1 << 11)
+#define ARES_NI_IDN                     (1 << 10)
+#define ARES_NI_IDN_ALLOW_UNASSIGNED    (1 << 11)
 #define ARES_NI_IDN_USE_STD3_ASCII_RULES (1 << 12)
 
 /* Addrinfo flag values */
-#define ARES_AI_CANONNAME              (1 << 0)
-#define ARES_AI_NUMERICHOST            (1 << 1)
-#define ARES_AI_PASSIVE                        (1 << 2)
-#define ARES_AI_NUMERICSERV            (1 << 3)
-#define ARES_AI_V4MAPPED               (1 << 4)
-#define ARES_AI_ALL                    (1 << 5)
-#define ARES_AI_ADDRCONFIG             (1 << 6)
+#define ARES_AI_CANONNAME               (1 << 0)
+#define ARES_AI_NUMERICHOST             (1 << 1)
+#define ARES_AI_PASSIVE                 (1 << 2)
+#define ARES_AI_NUMERICSERV             (1 << 3)
+#define ARES_AI_V4MAPPED                (1 << 4)
+#define ARES_AI_ALL                     (1 << 5)
+#define ARES_AI_ADDRCONFIG              (1 << 6)
 /* Reserved for future use */
-#define ARES_AI_IDN                    (1 << 10)
-#define ARES_AI_IDN_ALLOW_UNASSIGNED   (1 << 11)
+#define ARES_AI_IDN                     (1 << 10)
+#define ARES_AI_IDN_ALLOW_UNASSIGNED    (1 << 11)
 #define ARES_AI_IDN_USE_STD3_ASCII_RULES (1 << 12)
-#define ARES_AI_CANONIDN               (1 << 13)
+#define ARES_AI_CANONIDN                (1 << 13)
 
-#define ARES_AI_MASK                   (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
-                                        ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
-                                        ARES_AI_ADDRCONFIG)
+#define ARES_AI_MASK (ARES_AI_CANONNAME|ARES_AI_NUMERICHOST|ARES_AI_PASSIVE| \
+                      ARES_AI_NUMERICSERV|ARES_AI_V4MAPPED|ARES_AI_ALL| \
+                      ARES_AI_ADDRCONFIG)
+#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about this
+                                  many sockets */
+#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
+#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
+                                         ARES_GETSOCK_MAXNUM)))
 
 struct ares_options {
   int flags;
@@ -172,9 +177,11 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
 void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen,
                         int family, ares_host_callback callback, void *arg);
 void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa,
-                      socklen_t salen, int flags, ares_nameinfo_callback callback,
+                      socklen_t salen, int flags,
+                      ares_nameinfo_callback callback,
                       void *arg);
 int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
+int ares_getsock(ares_channel channel, int *socks, int numsocks);
 struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
                              struct timeval *tv);
 void ares_process(ares_channel channel, fd_set *read_fds, fd_set *write_fds);
diff --git a/ares_getsock.3 b/ares_getsock.3
new file mode 100644 (file)
index 0000000..301d8c2
--- /dev/null
@@ -0,0 +1,56 @@
+.\" $Id$
+.\"
+.\" Copyright 1998 by Daniel Stenberg
+.\"
+.\" Permission to use, copy, modify, and distribute this
+.\" software and its documentation for any purpose and without
+.\" fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright
+.\" notice and this permission notice appear in supporting
+.\" documentation, and that the name of M.I.T. not be used in
+.\" advertising or publicity pertaining to distribution of the
+.\" software without specific, written prior permission.
+.\" M.I.T. makes no representations about the suitability of
+.\" this software for any purpose.  It is provided "as is"
+.\" without express or implied warranty.
+.\"
+.TH ARES_GETSOCK 3 "22 December 2005"
+.SH NAME
+ares_getsock \- get file descriptors to wait on
+.SH SYNOPSIS
+.nf
+.B #include <ares.h>
+.PP
+.B int ares_getsock(ares_channel \fIchannel\fP, int *\fIsocks\fP, 
+.B int \fInumsocks\fP);
+.fi
+.SH DESCRIPTION
+The
+.B ares_getsock
+function retrieves the set of file descriptors which the calling
+application should wait on for reading and/or writing for the
+processing of name service queries pending on the name service channel
+identified by
+.IR channel .
+File descriptors will be set in the integer array pointed to by
+\fIsocks\fP.
+\fInumsocks\fP is the size of the given array in number of ints.
+
+This function can only return information about up to 16 sockets. If more are
+in use (however unlikely that is), they are simply not reported back.
+.SH RETURN VALUES
+\fBares_getsock\fP returns a bitmask for what actions to wait for on the
+different sockets. The ares.h header file provides these convenience macros to
+extract the information appropriately:
+
+.nf
+#define ARES_GETSOCK_MAXNUM 16 /* ares_getsock() can return info about
+                                  this many sockets */
+#define ARES_GETSOCK_READABLE(bits,num) (bits & (1<< (num)))
+#define ARES_GETSOCK_WRITABLE(bits,num) (bits & (1 << ((num) + \
+                                         ARES_GETSOCK_MAXNUM)))
+.fi
+.SH SEE ALSO
+.BR ares_timeout (3),
+.BR ares_fds (3),
+.BR ares_process (3)
diff --git a/ares_getsock.c b/ares_getsock.c
new file mode 100644 (file)
index 0000000..3c52a83
--- /dev/null
@@ -0,0 +1,71 @@
+/* $Id$ */
+
+/* Copyright 2005 by Daniel Stenberg.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  M.I.T. makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "setup.h"
+#include <sys/types.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#include "ares.h"
+#include "ares_private.h"
+
+int ares_getsock(ares_channel channel,
+                 int *s,
+                 int numsocks) /* size of the 'socks' array */
+{
+  struct server_state *server;
+  ares_socket_t nfds;
+  int i;
+  int sockindex=0;
+  int bitmap = 0;
+  unsigned int setbits = 0xffffffff;
+
+  ares_socket_t *socks = (ares_socket_t *)s;
+
+  /* No queries, no file descriptors. */
+  if (!channel->queries)
+    return 0;
+
+  nfds = 0;
+  for (i = 0; i < channel->nservers; i++)
+    {
+      server = &channel->servers[i];
+      if (server->udp_socket != ARES_SOCKET_BAD)
+        {
+          if(sockindex >= numsocks)
+            break;
+          socks[sockindex] = server->udp_socket;
+          bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
+          sockindex++;
+        }
+      if (server->tcp_socket != ARES_SOCKET_BAD)
+       {
+         if(sockindex >= numsocks)
+           break;
+         socks[sockindex] = server->tcp_socket;
+         bitmap |= ARES_GETSOCK_READABLE(setbits, sockindex);
+         sockindex++;
+
+         if (server->qhead) {
+           /* then the tcp socket is also writable! */
+           bitmap |= ARES_GETSOCK_WRITABLE(setbits, sockindex-1);
+         }
+
+       }
+    }
+  return (int)nfds;
+}