library init: be recursive
[platform/upstream/c-ares.git] / ares_query.c
index c5fc124..4bc9c25 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id$ */
 
 /* Copyright 1998 by the Massachusetts Institute of Technology.
  *
  * without express or implied warranty.
  */
 
-#include "setup.h"
+#include "ares_setup.h"
 
-#if defined(WIN32) && !defined(WATT32)
-#include "nameser.h"
+#ifdef HAVE_NETINET_IN_H
+#  include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_NAMESER_H
+#  include <arpa/nameser.h>
 #else
-#include <netinet/in.h>
-#include <arpa/nameser.h>
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-#include <arpa/nameser_compat.h>
+#  include "nameser.h"
 #endif
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#  include <arpa/nameser_compat.h>
 #endif
 
-#include <stdlib.h>
 #include "ares.h"
 #include "ares_dns.h"
 #include "ares_private.h"
@@ -39,7 +39,7 @@ struct qquery {
 
 static void qcallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen);
 
-void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
+static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
 {
   unsigned char x;
   unsigned char y;
@@ -53,30 +53,34 @@ void ares__rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len)
   state = &key->state[0];
   for(counter = 0; counter < buffer_len; counter ++)
   {
-       x = (x + 1) % 256;
-       y = (state[x] + y) % 256;
-       ARES_SWAP_BYTE(&state[x], &state[y]);
+    x = (unsigned char)((x + 1) % 256);
+    y = (unsigned char)((state[x] + y) % 256);
+    ARES_SWAP_BYTE(&state[x], &state[y]);
 
-       xorIndex = (state[x] + state[y]) % 256;
+    xorIndex = (unsigned char)((state[x] + state[y]) % 256);
 
-       buffer_ptr[counter] ^= state[xorIndex];
+    buffer_ptr[counter] = (unsigned char)(buffer_ptr[counter]^state[xorIndex]);
   }
   key->x = x;
   key->y = y;
 }
 
-static struct query* find_query_by_id(ares_channel channel, int id)
+static struct query* find_query_by_id(ares_channel channel, unsigned short id)
 {
   unsigned short qid;
-  struct query* q;
+  struct list_node* list_head;
+  struct list_node* list_node;
   DNS_HEADER_SET_QID(((unsigned char*)&qid), id);
 
   /* Find the query corresponding to this packet. */
-  for (q = channel->queries; q; q = q->next)
-  {
-       if (q->qid == qid)
+  list_head = &(channel->queries_by_qid[qid % ARES_QID_TABLE_SIZE]);
+  for (list_node = list_head->next; list_node != list_head;
+       list_node = list_node->next)
+    {
+       struct query *q = list_node->data;
+       if (q->qid == qid)
          return q;
-  }
+    }
   return NULL;
 }
 
@@ -86,15 +90,22 @@ static struct query* find_query_by_id(ares_channel channel, int id)
    performed per id generation. In practice this search should happen only
    once per newly generated id
 */
-static int generate_unique_id(ares_channel channel)
+static unsigned short generate_unique_id(ares_channel channel)
 {
-  int id;
+  unsigned short id;
 
   do {
-       id = ares__generate_new_id(&channel->id_key);
-  } while (find_query_by_id(channel,id));
+    id = ares__generate_new_id(&channel->id_key);
+  } while (find_query_by_id(channel, id));
 
-  return id;
+  return (unsigned short)id;
+}
+
+unsigned short ares__generate_new_id(rc4_key* key)
+{
+  unsigned short r=0;
+  rc4(key, (unsigned char *)&r, sizeof(r));
+  return r;
 }
 
 void ares_query(ares_channel channel, const char *name, int dnsclass,
@@ -106,8 +117,8 @@ void ares_query(ares_channel channel, const char *name, int dnsclass,
 
   /* Compose the query. */
   rd = !(channel->flags & ARES_FLAG_NORECURSE);
-  status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf,
-                        &qlen);
+  status = ares_create_query(name, dnsclass, type, channel->next_id, rd, &qbuf,
+              &qlen, (channel->flags & ARES_FLAG_EDNS) ? channel->ednspsz : 0);
   if (status != ARES_SUCCESS)
     {
       if (qbuf != NULL) free(qbuf);