added gnutls backend and moved backend code into new files
[ircu2.10.12-pk.git] / ircd / ircd_res.c
index 02ca4e47ddd6ccfc7134aae1e55431295badbbc5..627e12e826fa813361d0a2737b7e8543aa383ec9 100644 (file)
@@ -56,6 +56,10 @@ static struct Socket res_socket_v4;
 static struct Socket res_socket_v6;
 /** Next DNS lookup timeout. */
 static struct Timer res_timeout;
+/** Local address for IPv4 DNS lookups. */
+struct irc_sockaddr VirtualHost_dns_v4;
+/** Local address for IPv6 DNS lookups. */
+struct irc_sockaddr VirtualHost_dns_v6;
 /** Check for whether the resolver has been initialized yet. */
 #define resolver_started() (request_list.next != NULL)
 
@@ -142,6 +146,16 @@ extern struct irc_sockaddr irc_nsaddr_list[IRCD_MAXNS];
 extern int irc_nscount;
 extern char irc_domain[HOSTLEN];
 
+/** Prepare the resolver library to (optionally) accept a list of
+ * DNS servers through add_dns_server().
+ */
+void clear_nameservers(void)
+{
+  irc_nscount = 0;
+  memset(&VirtualHost_dns_v4, 0, sizeof(VirtualHost_dns_v4));
+  memset(&VirtualHost_dns_v6, 0, sizeof(VirtualHost_dns_v6));
+}
+
 /** Check whether \a inp is a nameserver we use.
  * @param[in] inp Nameserver address.
  * @return Non-zero if we trust \a inp; zero if not.
@@ -166,26 +180,43 @@ res_ourserver(const struct irc_sockaddr *inp)
 void
 restart_resolver(void)
 {
+  int need_v4;
+  int need_v6;
+  int ns;
+
   irc_res_init();
 
   if (!request_list.next)
     request_list.next = request_list.prev = &request_list;
 
-  if (!s_active(&res_socket_v4))
+  /* Check which address family (or families) our nameservers use. */
+  for (need_v4 = need_v6 = ns = 0; ns < irc_nscount; ns++)
   {
-    int fd = os_socket(&VirtualHost_v4, SOCK_DGRAM, "Resolver UDPv4 socket");
+    if (irc_in_addr_is_ipv4(&irc_nsaddr_list[ns].addr))
+      need_v4 = 1;
+    else
+      need_v6 = 1;
+  }
+
+  /* If we need an IPv4 socket, and don't have one, open it. */
+  if (need_v4 && !s_active(&res_socket_v4))
+  {
+    int fd = os_socket(&VirtualHost_dns_v4, SOCK_DGRAM, "Resolver UDPv4 socket", AF_INET);
     if (fd >= 0)
       socket_add(&res_socket_v4, res_readreply, NULL,
                  SS_DATAGRAM, SOCK_EVENT_READABLE, fd);
   }
 
-  if (!s_active(&res_socket_v6))
+#ifdef AF_INET6
+  /* If we need an IPv6 socket, and don't have one, open it. */
+  if (need_v6 && !s_active(&res_socket_v6))
   {
-    int fd = os_socket(&VirtualHost_v6, SOCK_DGRAM, "Resolver UDPv6 socket");
+    int fd = os_socket(&VirtualHost_dns_v6, SOCK_DGRAM, "Resolver UDPv6 socket", AF_INET6);
     if (fd >= 0)
       socket_add(&res_socket_v6, res_readreply, NULL,
                  SS_DATAGRAM, SOCK_EVENT_READABLE, fd);
   }
+#endif
 
   if (s_active(&res_socket_v4) || s_active(&res_socket_v6))
     timer_init(&res_timeout);
@@ -602,7 +633,6 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
 {
   char hostbuf[HOSTLEN + 100]; /* working buffer */
   unsigned char *current;      /* current position in buf */
-  int query_class;             /* answer class */
   int type;                    /* answer type */
   int n;                       /* temp count */
   int rd_length;
@@ -656,9 +686,8 @@ proc_answer(struct reslist *request, HEADER* header, char* buf, char* eob)
     type = irc_ns_get16(current);
     current += TYPE_SIZE;
 
-    query_class = irc_ns_get16(current);
+    /* We do not use the class or TTL values. */
     current += CLASS_SIZE;
-
     current += TTL_SIZE;
 
     rd_length = irc_ns_get16(current);