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

ares_gethostbyname.c File Reference

#include "ares_private.h"

Include dependency graph for ares_gethostbyname.c:

Go to the source code of this file.

Data Structures

struct  host_query

Functions

void next_lookup (struct host_query *hquery)
void host_callback (void *arg, int status, unsigned char *abuf, int alen)
void end_hquery (struct host_query *hquery, int status, struct hostent *host)
int fake_hostent (const char *name, ares_host_callback callback, void *arg)
void sort_addresses (struct hostent *host, struct apattern *sortlist, int nsort)
int get_address_index (struct in_addr *addr, struct apattern *sortlist, int nsort)
void ares_gethostbyname (ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg)


Function Documentation

void ares_gethostbyname ares_channel  channel,
const char *  name,
int  family,
ares_host_callback  callback,
void *  arg
 

Definition at line 47 of file ares_gethostbyname.c.

References AF_INET, ares_channel, ARES_ENOMEM, ARES_ENOTIMP, ares_host_callback, callback(), fake_hostent(), free, ares_channeldata::lookups, malloc, name, next_lookup(), NULL, and strdup.

Referenced by dns_client(), and gethostbynameaddr().

00049 {
00050   struct host_query *hquery;
00051 
00052   /* Right now we only know how to look up Internet addresses. */
00053   if (family != AF_INET)
00054     {
00055       callback(arg, ARES_ENOTIMP, NULL);
00056       return;
00057     }
00058 
00059   if (fake_hostent(name, callback, arg))
00060     return;
00061 
00062   /* Allocate and fill in the host query structure. */
00063   hquery = malloc(sizeof(struct host_query));
00064   if (!hquery)
00065     {
00066       callback(arg, ARES_ENOMEM, NULL);
00067       return;
00068     }
00069 
00070   hquery->channel = channel;
00071   hquery->name = strdup(name);
00072   if (!hquery->name)
00073     {
00074       free(hquery);
00075       callback(arg, ARES_ENOMEM, NULL);
00076       return;
00077     }
00078 
00079   hquery->callback = callback;
00080   hquery->arg = arg;
00081   hquery->remaining_lookups = channel->lookups;
00082 
00083   /* Start performing lookups according to channel->lookups. */
00084   next_lookup(hquery);
00085 }

Here is the call graph for this function:

void end_hquery struct host_query hquery,
int  status,
struct hostent host
[static]
 

Definition at line 129 of file ares_gethostbyname.c.

References ares_free_hostent(), host_query::arg, host_query::callback, free, host_query::name, and status.

Referenced by host_callback(), and next_lookup().

00131 {
00132   hquery->callback(hquery->arg, status, host);
00133   if (host)
00134     ares_free_hostent(host);
00135   free(hquery->name);
00136   free(hquery);
00137 }

Here is the call graph for this function:

int fake_hostent const char *  name,
ares_host_callback  callback,
void *  arg
[static]
 

Definition at line 142 of file ares_gethostbyname.c.

References AF_INET, ARES_EBADNAME, ARES_ENOMEM, ares_host_callback, ARES_SUCCESS, callback(), free, hostent::h_addr_list, hostent::h_addrtype, hostent::h_aliases, hostent::h_length, hostent::h_name, INADDR_NONE, inet_addr(), name, NULL, in_addr::s_addr, and strdup.

Referenced by ares_gethostbyname().

00144 {
00145   struct in_addr addr;
00146   struct hostent hostent;
00147   const char *p;
00148   char *aliases[1] = { NULL };
00149   char *addrs[2];
00150 
00151   /* It only looks like an IP address if it's all numbers and dots. */
00152   for (p = name; *p; p++)
00153     {
00154       if (!isdigit((unsigned char)*p) && *p != '.')
00155         return 0;
00156     }
00157 
00158   /* It also only looks like an IP address if it's non-zero-length and
00159    * doesn't end with a dot.
00160    */
00161   if (p == name || *(p - 1) == '.')
00162     return 0;
00163 
00164   /* It looks like an IP address.  Figure out what IP address it is. */
00165   addr.s_addr = inet_addr(name);
00166   if (addr.s_addr == INADDR_NONE)
00167     {
00168       callback(arg, ARES_EBADNAME, NULL);
00169       return 1;
00170     }
00171 
00172   /* Duplicate the name, to avoid a constness violation. */
00173   hostent.h_name = strdup(name);
00174   if (!hostent.h_name)
00175     {
00176       callback(arg, ARES_ENOMEM, NULL);
00177       return 1;
00178     }
00179 
00180   /* Fill in the rest of the host structure and terminate the query. */
00181   addrs[0] = (char *) &addr;
00182   addrs[1] = NULL;
00183   hostent.h_aliases = aliases;
00184   hostent.h_addrtype = AF_INET;
00185   hostent.h_length = sizeof(struct in_addr);
00186   hostent.h_addr_list = addrs;
00187   callback(arg, ARES_SUCCESS, &hostent);
00188 
00189   free(hostent.h_name);
00190   return 1;
00191 }

Here is the call graph for this function:

int get_address_index struct in_addr addr,
struct apattern sortlist,
int  nsort
[static]
 

Definition at line 223 of file ares_gethostbyname.c.

References apattern::addr, apattern::mask, and in_addr::s_addr.

Referenced by sort_addresses().

00225 {
00226   int i;
00227 
00228   for (i = 0; i < nsort; i++)
00229     {
00230       if ((addr->s_addr & sortlist[i].mask.s_addr) == sortlist[i].addr.s_addr)
00231         break;
00232     }
00233   return i;
00234 }

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

Definition at line 110 of file ares_gethostbyname.c.

References ares_channel, ARES_EDESTRUCTION, ares_parse_a_reply(), ARES_SUCCESS, end_hquery(), next_lookup(), ares_channeldata::nsort, NULL, sort_addresses(), ares_channeldata::sortlist, and status.

Referenced by next_lookup().

00111 {
00112   struct host_query *hquery = (struct host_query *) arg;
00113   ares_channel channel = hquery->channel;
00114   struct hostent *host;
00115 
00116   if (status == ARES_SUCCESS)
00117     {
00118       status = ares_parse_a_reply(abuf, alen, &host);
00119       if (host && channel->nsort)
00120         sort_addresses(host, channel->sortlist, channel->nsort);
00121       end_hquery(hquery, status, host);
00122     }
00123   else if (status == ARES_EDESTRUCTION)
00124     end_hquery(hquery, status, NULL);
00125   else
00126     next_lookup(hquery);
00127 }

Here is the call graph for this function:

void next_lookup struct host_query hquery  )  [static]
 

Definition at line 87 of file ares_gethostbyname.c.

References ARES_ENOTFOUND, ares_search(), C_IN, host_query::channel, end_hquery(), host_callback(), host_query::name, NULL, host_query::remaining_lookups, and T_A.

Referenced by addr_callback(), ares_gethostbyaddr(), ares_gethostbyname(), and host_callback().

00088 {
00089   const char *p;
00090 
00091   for (p = hquery->remaining_lookups; *p; p++)
00092     {
00093       switch (*p)
00094         {
00095         case 'b':
00096           /* DNS lookup */
00097           hquery->remaining_lookups = p + 1;
00098           ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback,
00099                       hquery);
00100           return;
00101 
00102         case 'f':
00103           /* Host file lookup */
00104           break;
00105         }
00106     }
00107   end_hquery(hquery, ARES_ENOTFOUND, NULL);
00108 }

Here is the call graph for this function:

void sort_addresses struct hostent host,
struct apattern sortlist,
int  nsort
[static]
 

Definition at line 193 of file ares_gethostbyname.c.

References get_address_index(), and hostent::h_addr_list.

Referenced by host_callback().

00195 {
00196   struct in_addr a1, a2;
00197   int i1, i2, ind1, ind2;
00198 
00199   /* This is a simple insertion sort, not optimized at all.  i1 walks
00200    * through the address list, with the loop invariant that everything
00201    * to the left of i1 is sorted.  In the loop body, the value at i1 is moved
00202    * back through the list (via i2) until it is in sorted order.
00203    */
00204   for (i1 = 0; host->h_addr_list[i1]; i1++)
00205     {
00206       memcpy(&a1, host->h_addr_list[i1], sizeof(struct in_addr));
00207       ind1 = get_address_index(&a1, sortlist, nsort);
00208       for (i2 = i1 - 1; i2 >= 0; i2--)
00209         {
00210           memcpy(&a2, host->h_addr_list[i2], sizeof(struct in_addr));
00211           ind2 = get_address_index(&a2, sortlist, nsort);
00212           if (ind2 <= ind1)
00213             break;
00214           memcpy(host->h_addr_list[i2 + 1], &a2, sizeof(struct in_addr));
00215         }
00216       memcpy(host->h_addr_list[i2 + 1], &a1, sizeof(struct in_addr));
00217     }
00218 }

Here is the call graph for this function:


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