Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

ares_search.c File Reference

#include "ares_private.h"

Include dependency graph for ares_search.c:

Go to the source code of this file.

Data Structures

struct  search_query

Functions

void search_callback (void *arg, int status, unsigned char *abuf, int alen)
void end_squery (struct search_query *squery, int status, unsigned char *abuf, int alen)
int cat_domain (const char *name, const char *domain, char **s)
int single_domain (ares_channel channel, const char *name, char **s)
void ares_search (ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg)


Function Documentation

void ares_search ares_channel  channel,
const char *  name,
int  dnsclass,
int  type,
ares_callback  callback,
void *  arg
 

Definition at line 46 of file ares_search.c.

References ares_callback, ares_channel, ARES_ENOMEM, ares_query(), ARES_SUCCESS, callback(), cat_domain(), ares_channeldata::domains, free, malloc, name, ares_channeldata::ndots, NULL, search_callback(), single_domain(), status, and strdup.

Referenced by next_lookup().

00048 {
00049   struct search_query *squery;
00050   char *s;
00051   const char *p;
00052   int status, ndots;
00053   
00054   /* If name only yields one domain to search, then we don't have
00055    * to keep extra state, so just do an ares_query().
00056    */
00057   status = single_domain(channel, name, &s);
00058   if (status != ARES_SUCCESS)
00059     {
00060       callback(arg, status, NULL, 0);
00061       return;
00062     }
00063   if (s)
00064     {
00065       ares_query(channel, s, dnsclass, type, callback, arg);
00066       free(s);
00067       return;
00068     }
00069   
00070   /* Allocate a search_query structure to hold the state necessary for
00071    * doing multiple lookups.
00072    */
00073   squery = malloc(sizeof(struct search_query));
00074   if (!squery)
00075     {
00076       callback(arg, ARES_ENOMEM, NULL, 0);
00077       return;
00078     }
00079   squery->channel = channel;
00080   squery->name = strdup(name);
00081   if(!squery->name)
00082     {
00083       free(squery);
00084       callback(arg, ARES_ENOMEM, NULL, 0);
00085       return;
00086     }
00087   squery->dnsclass = dnsclass;
00088   squery->type = type;
00089   squery->status_as_is = -1;
00090   squery->callback = callback;
00091   squery->arg = arg;
00092   
00093   /* Count the number of dots in name. */
00094   ndots = 0;
00095   for (p = name; *p; p++)
00096     {
00097       if (*p == '.')
00098         ndots++;
00099     }
00100   
00101   /* If ndots is at least the channel ndots threshold (usually 1),
00102    * then we try the name as-is first.  Otherwise, we try the name
00103    * as-is last.
00104    */
00105   if (ndots >= channel->ndots)
00106     {
00107       /* Try the name as-is first. */
00108       squery->next_domain = 0;
00109       squery->trying_as_is = 1;
00110       ares_query(channel, name, dnsclass, type, search_callback, squery);
00111     }
00112   else
00113     {
00114       /* Try the name as-is last; start with the first search domain. */
00115       squery->next_domain = 1;
00116       squery->trying_as_is = 0;
00117       status = cat_domain(name, channel->domains[0], &s);
00118       if (status == ARES_SUCCESS)
00119         {
00120           ares_query(channel, s, dnsclass, type, search_callback, squery);
00121           free(s);
00122         }
00123       else
00124         callback(arg, status, NULL, 0);
00125     }
00126 }

Here is the call graph for this function:

int cat_domain const char *  name,
const char *  domain,
char **  s
[static]
 

Definition at line 181 of file ares_search.c.

References ARES_ENOMEM, ARES_SUCCESS, malloc, and name.

Referenced by ares_search(), and search_callback().

00182 {
00183   int nlen = strlen(name), dlen = strlen(domain);
00184   
00185   *s = malloc(nlen + 1 + dlen + 1);
00186   if (!*s)
00187     return ARES_ENOMEM;
00188   memcpy(*s, name, nlen);
00189   (*s)[nlen] = '.';
00190   memcpy(*s + nlen + 1, domain, dlen);
00191   (*s)[nlen + 1 + dlen] = 0;
00192   return ARES_SUCCESS;
00193 }

void end_squery struct search_query squery,
int  status,
unsigned char *  abuf,
int  alen
[static]
 

Definition at line 172 of file ares_search.c.

References search_query::arg, search_query::callback, free, search_query::name, and status.

Referenced by search_callback().

00174 {
00175   squery->callback(squery->arg, status, abuf, alen);
00176   free(squery->name);
00177   free(squery);
00178 }

void search_callback void *  arg,
int  status,
unsigned char *  abuf,
int  alen
[static]
 

Definition at line 128 of file ares_search.c.

References ares_channel, ARES_ENODATA, ARES_ENOTFOUND, ARES_ESERVFAIL, ares_query(), ARES_SUCCESS, cat_domain(), ares_channeldata::domains, end_squery(), free, ares_channeldata::ndomains, NULL, search_callback(), and status.

Referenced by ares_search(), and search_callback().

00130 {
00131   struct search_query *squery = (struct search_query *) arg;
00132   ares_channel channel = squery->channel;
00133   char *s;
00134   
00135   /* Stop searching unless we got a non-fatal error. */
00136   if (status != ARES_ENODATA && status != ARES_ESERVFAIL
00137       && status != ARES_ENOTFOUND)
00138     end_squery(squery, status, abuf, alen);
00139   else
00140     {
00141       /* Save the status if we were trying as-is. */
00142       if (squery->trying_as_is)
00143         squery->status_as_is = status;
00144       if (squery->next_domain < channel->ndomains)
00145         {
00146           /* Try the next domain. */
00147           status = cat_domain(squery->name,
00148                               channel->domains[squery->next_domain], &s);
00149           if (status != ARES_SUCCESS)
00150             end_squery(squery, status, NULL, 0);
00151           else
00152             {
00153               squery->trying_as_is = 0;
00154               squery->next_domain++;
00155               ares_query(channel, s, squery->dnsclass, squery->type,
00156                          search_callback, squery);
00157               free(s);
00158             }
00159         }
00160       else if (squery->status_as_is == -1)
00161         {
00162           /* Try the name as-is at the end. */
00163           squery->trying_as_is = 1;
00164           ares_query(channel, squery->name, squery->dnsclass, squery->type,
00165                      search_callback, squery);
00166         }
00167       else
00168         end_squery(squery, squery->status_as_is, NULL, 0);
00169     }
00170 }

Here is the call graph for this function:

int single_domain ares_channel  channel,
const char *  name,
char **  s
[static]
 

Definition at line 199 of file ares_search.c.

References ares_channel, ARES_ENOMEM, ARES_FLAG_NOSEARCH, ARES_SUCCESS, ares_channeldata::flags, len, name, ares_channeldata::ndomains, NULL, and strdup.

Referenced by ares_search().

00200 {
00201   int len = strlen(name);
00202   
00203   /* If the name contains a trailing dot, then the single query is the name
00204    * sans the trailing dot.
00205    */
00206   if (name[len - 1] == '.')
00207     {
00208       *s = strdup(name);
00209       return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
00210     }
00211   
00212   if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0)
00213     {
00214       /* No domain search to do; just try the name as-is. */
00215       *s = strdup(name);
00216       return (*s) ? ARES_SUCCESS : ARES_ENOMEM;
00217     }
00218   
00219   *s = NULL;
00220   return ARES_SUCCESS;
00221 }


Generated on Wed Jan 14 12:59:01 2004 for RTL-lwIP-0.4 by doxygen 1.3.4