This graph shows which files directly or indirectly include this file:
Go to the source code of this file.
Data Structures | |
struct | ares_options |
Defines | |
#define | ARES_SUCCESS 0 |
#define | ARES_ENODATA 1 |
#define | ARES_EFORMERR 2 |
#define | ARES_ESERVFAIL 3 |
#define | ARES_ENOTFOUND 4 |
#define | ARES_ENOTIMP 5 |
#define | ARES_EREFUSED 6 |
#define | ARES_EBADQUERY 7 |
#define | ARES_EBADNAME 8 |
#define | ARES_EBADFAMILY 9 |
#define | ARES_EBADRESP 10 |
#define | ARES_ECONNREFUSED 11 |
#define | ARES_ETIMEOUT 12 |
#define | ARES_EOF 13 |
#define | ARES_EFILE 14 |
#define | ARES_ENOMEM 15 |
#define | ARES_EDESTRUCTION 16 |
#define | ARES_FLAG_USEVC (1 << 0) |
#define | ARES_FLAG_PRIMARY (1 << 1) |
#define | ARES_FLAG_IGNTC (1 << 2) |
#define | ARES_FLAG_NORECURSE (1 << 3) |
#define | ARES_FLAG_STAYOPEN (1 << 4) |
#define | ARES_FLAG_NOSEARCH (1 << 5) |
#define | ARES_FLAG_NOALIASES (1 << 6) |
#define | ARES_FLAG_NOCHECKRESP (1 << 7) |
#define | ARES_OPT_FLAGS (1 << 0) |
#define | ARES_OPT_TIMEOUT (1 << 1) |
#define | ARES_OPT_TRIES (1 << 2) |
#define | ARES_OPT_NDOTS (1 << 3) |
#define | ARES_OPT_UDP_PORT (1 << 4) |
#define | ARES_OPT_TCP_PORT (1 << 5) |
#define | ARES_OPT_SERVERS (1 << 6) |
#define | ARES_OPT_DOMAINS (1 << 7) |
#define | ARES_OPT_LOOKUPS (1 << 8) |
Typedefs | |
typedef ares_channeldata * | ares_channel |
typedef void(* | ares_callback )(void *arg, int status, unsigned char *abuf, int alen) |
typedef void(* | ares_host_callback )(void *arg, int status, struct hostent *hostent) |
Functions | |
int | ares_init (ares_channel *channelptr) |
int | ares_init_options (ares_channel *channelptr, struct ares_options *options, int optmask) |
void | ares_destroy (ares_channel channel) |
void | ares_send (ares_channel channel, const unsigned char *qbuf, int qlen, ares_callback callback, void *arg) |
void | ares_query (ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) |
void | ares_search (ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) |
void | ares_gethostbyname (ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg) |
void | ares_gethostbyaddr (ares_channel channel, const void *addr, int addrlen, int family, ares_host_callback callback, void *arg) |
int | ares_fds (ares_channel channel, fd_set *read_fds, fd_set *write_fds) |
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) |
int | ares_mkquery (const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen) |
int | ares_expand_name (const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, int *enclen) |
int | ares_parse_a_reply (const unsigned char *abuf, int alen, struct hostent **host) |
int | ares_parse_ptr_reply (const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host) |
void | ares_free_string (unsigned char *str) |
void | ares_free_hostent (struct hostent *host) |
const char * | ares_strerror (int code, char **memptr) |
void | ares_free_errmem (char *mem) |
|
|
|
Definition at line 40 of file ares.h. Referenced by ares_expand_name(), ares_mkquery(), and fake_hostent(). |
|
Definition at line 39 of file ares.h. Referenced by ares_send(). |
|
Definition at line 42 of file ares.h. Referenced by ares_parse_a_reply(), and ares_parse_ptr_reply(). |
|
Definition at line 43 of file ares.h. Referenced by ares_send(). |
|
Definition at line 48 of file ares.h. Referenced by addr_callback(), ares_destroy(), and host_callback(). |
|
|
|
Definition at line 32 of file ares.h. Referenced by qcallback(). |
|
Definition at line 31 of file ares.h. Referenced by ares_parse_a_reply(), ares_parse_ptr_reply(), qcallback(), and search_callback(). |
|
Definition at line 47 of file ares.h. Referenced by ares__send_query(), ares_expand_name(), ares_gethostbyaddr(), ares_gethostbyname(), ares_init_options(), ares_mkquery(), ares_parse_a_reply(), ares_parse_ptr_reply(), ares_query(), ares_search(), ares_send(), cat_domain(), fake_hostent(), init_by_defaults(), init_by_options(), and single_domain(). |
|
Definition at line 34 of file ares.h. Referenced by gethostbynameaddr(), next_lookup(), qcallback(), and search_callback(). |
|
Definition at line 35 of file ares.h. Referenced by ares_gethostbyaddr(), ares_gethostbyname(), and qcallback(). |
|
|
|
Definition at line 36 of file ares.h. Referenced by qcallback(). |
|
Definition at line 33 of file ares.h. Referenced by qcallback(), and search_callback(). |
|
Definition at line 44 of file ares.h. Referenced by process_timeouts(). |
|
Definition at line 53 of file ares.h. Referenced by process_answer(). |
|
|
|
Definition at line 58 of file ares.h. Referenced by process_answer(). |
|
Definition at line 54 of file ares.h. Referenced by ares_query(). |
|
Definition at line 56 of file ares.h. Referenced by single_domain(). |
|
Definition at line 52 of file ares.h. Referenced by ares_init_options(). |
|
Definition at line 55 of file ares.h. Referenced by end_query(). |
|
Definition at line 51 of file ares.h. Referenced by ares_send(), and dns_client(). |
|
Definition at line 68 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 61 of file ares.h. Referenced by dns_client(), and init_by_options(). |
|
Definition at line 69 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 64 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 67 of file ares.h. Referenced by dns_client(), gethostbynameaddr(), and init_by_options(). |
|
Definition at line 66 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 62 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 63 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 65 of file ares.h. Referenced by init_by_options(). |
|
Definition at line 28 of file ares.h. Referenced by addr_callback(), ares_expand_name(), ares_init_options(), ares_mkquery(), ares_parse_a_reply(), ares_parse_ptr_reply(), ares_query(), ares_search(), callback(), cat_domain(), dns_client(), dns_client_callback(), fake_hostent(), gethostbynameaddr(), host_callback(), init_by_defaults(), init_by_options(), process_answer(), qcallback(), same_questions(), search_callback(), and single_domain(). |
|
Definition at line 87 of file ares.h. Referenced by ares_query(), ares_search(), and ares_send(). |
|
|
Definition at line 89 of file ares.h. Referenced by ares_gethostbyaddr(), ares_gethostbyname(), and fake_hostent(). |
|
Definition at line 25 of file ares_destroy.c. References ares__close_sockets(), ares_channel, ARES_EDESTRUCTION, query::callback, ares_channeldata::domains, free, ares_channeldata::lookups, ares_channeldata::ndomains, query::next, ares_channeldata::nservers, NULL, ares_channeldata::queries, ares_channeldata::servers, and ares_channeldata::sortlist. Referenced by dns_client(), and gethostbynameaddr().
00026 { 00027 int i; 00028 struct query *query; 00029 00030 for (i = 0; i < channel->nservers; i++) 00031 ares__close_sockets(&channel->servers[i]); 00032 free(channel->servers); 00033 for (i = 0; i < channel->ndomains; i++) 00034 free(channel->domains[i]); 00035 free(channel->domains); 00036 free(channel->sortlist); 00037 free(channel->lookups); 00038 while (channel->queries) 00039 { 00040 query = channel->queries; 00041 channel->queries = query->next; 00042 query->callback(query->arg, ARES_EDESTRUCTION, NULL, 0); 00043 free(query->tcpbuf); 00044 free(query->skip_server); 00045 free(query); 00046 } 00047 free(channel); 00048 } |
Here is the call graph for this function:
|
Definition at line 52 of file ares_expand_name.c. References ARES_EBADNAME, ARES_ENOMEM, ARES_SUCCESS, INDIR_MASK, len, malloc, and name_length(). Referenced by ares_parse_a_reply(), ares_parse_ptr_reply(), and same_questions().
00054 { 00055 int len, indir = 0; 00056 char *q; 00057 const unsigned char *p; 00058 00059 len = name_length(encoded, abuf, alen); 00060 if (len == -1) 00061 return ARES_EBADNAME; 00062 00063 *s = malloc(len + 1); 00064 if (!*s) 00065 return ARES_ENOMEM; 00066 q = *s; 00067 00068 /* No error-checking necessary; it was all done by name_length(). */ 00069 p = encoded; 00070 while (*p) 00071 { 00072 if ((*p & INDIR_MASK) == INDIR_MASK) 00073 { 00074 if (!indir) 00075 { 00076 *enclen = p + 2 - encoded; 00077 indir = 1; 00078 } 00079 p = abuf + ((*p & ~INDIR_MASK) << 8 | *(p + 1)); 00080 } 00081 else 00082 { 00083 len = *p; 00084 p++; 00085 while (len--) 00086 { 00087 if (*p == '.' || *p == '\\') 00088 *q++ = '\\'; 00089 *q++ = *p; 00090 p++; 00091 } 00092 *q++ = '.'; 00093 } 00094 } 00095 if (!indir) 00096 *enclen = p + 1 - encoded; 00097 00098 /* Nuke the trailing period if we wrote one. */ 00099 if (q > *s) 00100 *(q - 1) = 0; 00101 00102 return ARES_SUCCESS; 00103 } |
Here is the call graph for this function:
|
Definition at line 25 of file ares_fds.c. References ares_channel, FD_SET, ares_channeldata::nservers, ares_channeldata::queries, and ares_channeldata::servers. Referenced by dns_client(), and gethostbynameaddr().
00026 { 00027 struct server_state *server; 00028 int i, nfds; 00029 00030 /* No queries, no file descriptors. */ 00031 if (!channel->queries) 00032 return 0; 00033 00034 nfds = 0; 00035 for (i = 0; i < channel->nservers; i++) 00036 { 00037 server = &channel->servers[i]; 00038 if (server->udp_socket != -1) 00039 { 00040 FD_SET(server->udp_socket, read_fds); 00041 if (server->udp_socket >= nfds) 00042 nfds = server->udp_socket + 1; 00043 } 00044 if (server->tcp_socket != -1) 00045 { 00046 FD_SET(server->tcp_socket, read_fds); 00047 if (server->qhead) 00048 FD_SET(server->tcp_socket, write_fds); 00049 if (server->tcp_socket >= nfds) 00050 nfds = server->tcp_socket + 1; 00051 } 00052 } 00053 return nfds; 00054 } |
|
Definition at line 29 of file ares_free_errmem.c. Referenced by dns_client(), and dns_client_callback().
00030 {
00031 (void) mem;
00032 }
|
|
Definition at line 25 of file ares_free_hostent.c. References free, hostent::h_addr_list, hostent::h_aliases, and hostent::h_name. Referenced by end_aquery(), and end_hquery().
|
|
Definition at line 25 of file ares_free_string.c. References free. Referenced by ares_query().
00026 { 00027 free(str); 00028 } |
|
Definition at line 46 of file ares_gethostbyaddr.c. References AF_INET, ares_channel, ARES_ENOMEM, ARES_ENOTIMP, ares_host_callback, callback(), ares_channeldata::lookups, malloc, next_lookup(), and NULL. Referenced by dns_client(), and gethostbynameaddr().
00048 { 00049 struct addr_query *aquery; 00050 00051 if (family != AF_INET || addrlen != sizeof(struct in_addr)) 00052 { 00053 callback(arg, ARES_ENOTIMP, NULL); 00054 return; 00055 } 00056 00057 aquery = malloc(sizeof(struct addr_query)); 00058 if (!aquery) 00059 { 00060 callback(arg, ARES_ENOMEM, NULL); 00061 return; 00062 } 00063 aquery->channel = channel; 00064 memcpy(&aquery->addr, addr, sizeof(aquery->addr)); 00065 aquery->callback = callback; 00066 aquery->arg = arg; 00067 aquery->remaining_lookups = channel->lookups; 00068 00069 next_lookup(aquery); 00070 } |
Here is the call graph for this function:
|
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:
|
Definition at line 34 of file ares_init.c. References ares_channel, ares_init_options(), and NULL.
00035 { 00036 return ares_init_options(channelptr, NULL, 0); 00037 } |
Here is the call graph for this function:
|
Definition at line 40 of file ares_init.c. References ares_channel, ARES_ENOMEM, ARES_FLAG_PRIMARY, ARES_SUCCESS, ares_channeldata::domains, ares_channeldata::flags, free, gettimeofday(), init_by_defaults(), init_by_options(), ares_channeldata::lookups, malloc, ares_channeldata::ndomains, ares_channeldata::ndots, ares_channeldata::next_id, ares_channeldata::nservers, ares_channeldata::nsort, NULL, ares_channeldata::queries, ares_channeldata::servers, ares_channeldata::sortlist, status, ares_channeldata::tcp_port, time, ares_channeldata::timeout, ares_channeldata::tries, ares_channeldata::udp_port, and server_state::udp_socket. Referenced by ares_init(), dns_client(), and gethostbynameaddr().
00042 { 00043 ares_channel channel; 00044 int i, status; 00045 struct server_state *server; 00046 00047 channel = malloc(sizeof(struct ares_channeldata)); 00048 if (!channel) 00049 return ARES_ENOMEM; 00050 00051 /* Set everything to distinguished values so we know they haven't 00052 * been set yet. 00053 */ 00054 channel->flags = -1; 00055 channel->timeout = -1; 00056 channel->tries = -1; 00057 channel->ndots = -1; 00058 channel->udp_port = -1; 00059 channel->tcp_port = -1; 00060 channel->nservers = -1; 00061 channel->ndomains = -1; 00062 channel->nsort = -1; 00063 channel->lookups = NULL; 00064 00065 /* Initialize configuration by each of the four sources, from highest 00066 * precedence to lowest. 00067 */ 00068 status = init_by_options(channel, options, optmask); 00069 if (status == ARES_SUCCESS) 00070 status = init_by_defaults(channel); 00071 if (status != ARES_SUCCESS) 00072 { 00073 /* Something failed; clean up memory we may have allocated. */ 00074 if (channel->nservers != -1) 00075 free(channel->servers); 00076 if (channel->ndomains != -1) 00077 { 00078 for (i = 0; i < channel->ndomains; i++) 00079 free(channel->domains[i]); 00080 free(channel->domains); 00081 } 00082 if (channel->nsort != -1) 00083 free(channel->sortlist); 00084 free(channel->lookups); 00085 free(channel); 00086 return status; 00087 } 00088 00089 /* Trim to one server if ARES_FLAG_PRIMARY is set. */ 00090 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1) 00091 channel->nservers = 1; 00092 00093 /* Initialize server states. */ 00094 for (i = 0; i < channel->nservers; i++) 00095 { 00096 server = &channel->servers[i]; 00097 server->udp_socket = -1; 00098 server->tcp_socket = -1; 00099 server->tcp_lenbuf_pos = 0; 00100 server->tcp_buffer = NULL; 00101 server->qhead = NULL; 00102 server->qtail = NULL; 00103 } 00104 00105 /* Choose a somewhat random query ID. The main point is to avoid 00106 * collisions with stale queries. An attacker trying to spoof a DNS 00107 * answer also has to guess the query ID, but it's only a 16-bit 00108 * field, so there's not much to be done about that. 00109 */ 00110 00111 // channel->next_id = (RetrieveClock() ^ os_current_process()) & 0xffff; 00112 { 00113 struct timeval time; 00114 gettimeofday(&time,NULL); 00115 channel->next_id = (time.tv_usec ^ time.tv_sec) & 0xffff; 00116 } 00117 00118 channel->queries = NULL; 00119 00120 *channelptr = channel; 00121 return ARES_SUCCESS; 00122 } |
Here is the call graph for this function:
|
Definition at line 74 of file ares_mkquery.c. References ARES_EBADNAME, ARES_ENOMEM, ARES_SUCCESS, DNS_HEADER_SET_OPCODE, DNS_HEADER_SET_QDCOUNT, DNS_HEADER_SET_QID, DNS_HEADER_SET_RD, DNS_QUESTION_SET_CLASS, DNS_QUESTION_SET_TYPE, HFIXEDSZ, len, malloc, MAXLABEL, name, QFIXEDSZ, and QUERY. Referenced by ares_query().
00076 { 00077 int len; 00078 unsigned char *q; 00079 const char *p; 00080 00081 /* Compute the length of the encoded name so we can check buflen. 00082 * Start counting at 1 for the zero-length label at the end. */ 00083 len = 1; 00084 for (p = name; *p; p++) 00085 { 00086 if (*p == '\\' && *(p + 1) != 0) 00087 p++; 00088 len++; 00089 } 00090 /* If there are n periods in the name, there are n + 1 labels, and 00091 * thus n + 1 length fields, unless the name is empty or ends with a 00092 * period. So add 1 unless name is empty or ends with a period. 00093 */ 00094 if (*name && *(p - 1) != '.') 00095 len++; 00096 00097 *buflen = len + HFIXEDSZ + QFIXEDSZ; 00098 *buf = malloc(*buflen); 00099 if (!*buf) 00100 return ARES_ENOMEM; 00101 00102 /* Set up the header. */ 00103 q = *buf; 00104 memset(q, 0, HFIXEDSZ); 00105 DNS_HEADER_SET_QID(q, id); 00106 DNS_HEADER_SET_OPCODE(q, QUERY); 00107 DNS_HEADER_SET_RD(q, (rd) ? 1 : 0); 00108 DNS_HEADER_SET_QDCOUNT(q, 1); 00109 00110 /* A name of "." is a screw case for the loop below, so adjust it. */ 00111 if (strcmp(name, ".") == 0) 00112 name++; 00113 00114 /* Start writing out the name after the header. */ 00115 q += HFIXEDSZ; 00116 while (*name) 00117 { 00118 if (*name == '.') 00119 return ARES_EBADNAME; 00120 00121 /* Count the number of bytes in this label. */ 00122 len = 0; 00123 for (p = name; *p && *p != '.'; p++) 00124 { 00125 if (*p == '\\' && *(p + 1) != 0) 00126 p++; 00127 len++; 00128 } 00129 if (len > MAXLABEL) 00130 return ARES_EBADNAME; 00131 00132 /* Encode the length and copy the data. */ 00133 *q++ = len; 00134 for (p = name; *p && *p != '.'; p++) 00135 { 00136 if (*p == '\\' && *(p + 1) != 0) 00137 p++; 00138 *q++ = *p; 00139 } 00140 00141 /* Go to the next label and repeat, unless we hit the end. */ 00142 if (!*p) 00143 break; 00144 name = p + 1; 00145 } 00146 00147 /* Add the zero-length label at the end. */ 00148 *q++ = 0; 00149 00150 /* Finish off the question with the type and class. */ 00151 DNS_QUESTION_SET_TYPE(q, type); 00152 DNS_QUESTION_SET_CLASS(q, dnsclass); 00153 00154 return ARES_SUCCESS; 00155 } |
|
Definition at line 26 of file ares_parse_a_reply.c. References AF_INET, ARES_EBADRESP, ARES_ENODATA, ARES_ENOMEM, ares_expand_name(), ARES_SUCCESS, C_IN, DNS_HEADER_ANCOUNT, DNS_HEADER_QDCOUNT, DNS_RR_CLASS, DNS_RR_LEN, DNS_RR_TYPE, free, HFIXEDSZ, len, malloc, NULL, QFIXEDSZ, RRFIXEDSZ, status, strcasecmp, T_A, and T_CNAME. Referenced by host_callback().
00028 { 00029 unsigned int qdcount, ancount; 00030 int status, i, len, rr_type, rr_class, rr_len, naddrs; 00031 int naliases; 00032 const unsigned char *aptr; 00033 char *hostname, *rr_name, *rr_data, **aliases; 00034 struct in_addr *addrs; 00035 struct hostent *hostent; 00036 00037 /* Set *host to NULL for all failure cases. */ 00038 *host = NULL; 00039 00040 /* Give up if abuf doesn't have room for a header. */ 00041 if (alen < HFIXEDSZ) 00042 return ARES_EBADRESP; 00043 00044 /* Fetch the question and answer count from the header. */ 00045 qdcount = DNS_HEADER_QDCOUNT(abuf); 00046 ancount = DNS_HEADER_ANCOUNT(abuf); 00047 if (qdcount != 1) 00048 return ARES_EBADRESP; 00049 00050 /* Expand the name from the question, and skip past the question. */ 00051 aptr = abuf + HFIXEDSZ; 00052 status = ares_expand_name(aptr, abuf, alen, &hostname, &len); 00053 if (status != ARES_SUCCESS) 00054 return status; 00055 if (aptr + len + QFIXEDSZ > abuf + alen) 00056 { 00057 free(hostname); 00058 return ARES_EBADRESP; 00059 } 00060 aptr += len + QFIXEDSZ; 00061 00062 /* Allocate addresses and aliases; ancount gives an upper bound for both. */ 00063 addrs = malloc(ancount * sizeof(struct in_addr)); 00064 if (!addrs) 00065 { 00066 free(hostname); 00067 return ARES_ENOMEM; 00068 } 00069 aliases = malloc((ancount + 1) * sizeof(char *)); 00070 if (!aliases) 00071 { 00072 free(hostname); 00073 free(addrs); 00074 return ARES_ENOMEM; 00075 } 00076 naddrs = 0; 00077 naliases = 0; 00078 00079 /* Examine each answer resource record (RR) in turn. */ 00080 for (i = 0; i < ancount; i++) 00081 { 00082 /* Decode the RR up to the data field. */ 00083 status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); 00084 if (status != ARES_SUCCESS) 00085 break; 00086 aptr += len; 00087 if (aptr + RRFIXEDSZ > abuf + alen) 00088 { 00089 status = ARES_EBADRESP; 00090 break; 00091 } 00092 rr_type = DNS_RR_TYPE(aptr); 00093 rr_class = DNS_RR_CLASS(aptr); 00094 rr_len = DNS_RR_LEN(aptr); 00095 aptr += RRFIXEDSZ; 00096 00097 if (rr_class == C_IN && rr_type == T_A 00098 && rr_len == sizeof(struct in_addr) 00099 && strcasecmp(rr_name, hostname) == 0) 00100 { 00101 memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); 00102 naddrs++; 00103 status = ARES_SUCCESS; 00104 } 00105 00106 if (rr_class == C_IN && rr_type == T_CNAME) 00107 { 00108 /* Record the RR name as an alias. */ 00109 aliases[naliases] = rr_name; 00110 naliases++; 00111 00112 /* Decode the RR data and replace the hostname with it. */ 00113 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); 00114 if (status != ARES_SUCCESS) 00115 break; 00116 free(hostname); 00117 hostname = rr_data; 00118 } 00119 else 00120 free(rr_name); 00121 00122 aptr += rr_len; 00123 if (aptr > abuf + alen) 00124 { 00125 status = ARES_EBADRESP; 00126 break; 00127 } 00128 } 00129 00130 if (status == ARES_SUCCESS && naddrs == 0) 00131 status = ARES_ENODATA; 00132 if (status == ARES_SUCCESS) 00133 { 00134 /* We got our answer. Allocate memory to build the host entry. */ 00135 aliases[naliases] = NULL; 00136 hostent = malloc(sizeof(struct hostent)); 00137 if (hostent) 00138 { 00139 hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); 00140 if (hostent->h_addr_list) 00141 { 00142 /* Fill in the hostent and return successfully. */ 00143 hostent->h_name = hostname; 00144 hostent->h_aliases = aliases; 00145 hostent->h_addrtype = AF_INET; 00146 hostent->h_length = sizeof(struct in_addr); 00147 for (i = 0; i < naddrs; i++) 00148 hostent->h_addr_list[i] = (char *) &addrs[i]; 00149 hostent->h_addr_list[naddrs] = NULL; 00150 *host = hostent; 00151 return ARES_SUCCESS; 00152 } 00153 free(hostent); 00154 } 00155 status = ARES_ENOMEM; 00156 } 00157 for (i = 0; i < naliases; i++) 00158 free(aliases[i]); 00159 free(aliases); 00160 free(addrs); 00161 free(hostname); 00162 return status; 00163 } |
Here is the call graph for this function:
|
Definition at line 26 of file ares_parse_ptr_reply.c. References ARES_EBADRESP, ARES_ENODATA, ARES_ENOMEM, ares_expand_name(), ARES_SUCCESS, C_IN, DNS_HEADER_ANCOUNT, DNS_HEADER_QDCOUNT, DNS_RR_CLASS, DNS_RR_LEN, DNS_RR_TYPE, free, HFIXEDSZ, len, malloc, NULL, QFIXEDSZ, RRFIXEDSZ, status, strcasecmp, T_CNAME, and T_PTR. Referenced by addr_callback().
00028 { 00029 unsigned int qdcount, ancount; 00030 int status, i, len, rr_type, rr_class, rr_len; 00031 const unsigned char *aptr; 00032 char *ptrname, *hostname, *rr_name, *rr_data; 00033 struct hostent *hostent; 00034 00035 /* Set *host to NULL for all failure cases. */ 00036 *host = NULL; 00037 00038 /* Give up if abuf doesn't have room for a header. */ 00039 if (alen < HFIXEDSZ) 00040 return ARES_EBADRESP; 00041 00042 /* Fetch the question and answer count from the header. */ 00043 qdcount = DNS_HEADER_QDCOUNT(abuf); 00044 ancount = DNS_HEADER_ANCOUNT(abuf); 00045 if (qdcount != 1) 00046 return ARES_EBADRESP; 00047 00048 /* Expand the name from the question, and skip past the question. */ 00049 aptr = abuf + HFIXEDSZ; 00050 status = ares_expand_name(aptr, abuf, alen, &ptrname, &len); 00051 if (status != ARES_SUCCESS) 00052 return status; 00053 if (aptr + len + QFIXEDSZ > abuf + alen) 00054 { 00055 free(ptrname); 00056 return ARES_EBADRESP; 00057 } 00058 aptr += len + QFIXEDSZ; 00059 00060 /* Examine each answer resource record (RR) in turn. */ 00061 hostname = NULL; 00062 for (i = 0; i < ancount; i++) 00063 { 00064 /* Decode the RR up to the data field. */ 00065 status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); 00066 if (status != ARES_SUCCESS) 00067 break; 00068 aptr += len; 00069 if (aptr + RRFIXEDSZ > abuf + alen) 00070 { 00071 status = ARES_EBADRESP; 00072 break; 00073 } 00074 rr_type = DNS_RR_TYPE(aptr); 00075 rr_class = DNS_RR_CLASS(aptr); 00076 rr_len = DNS_RR_LEN(aptr); 00077 aptr += RRFIXEDSZ; 00078 00079 if (rr_class == C_IN && rr_type == T_PTR 00080 && strcasecmp(rr_name, ptrname) == 0) 00081 { 00082 /* Decode the RR data and set hostname to it. */ 00083 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); 00084 if (status != ARES_SUCCESS) 00085 break; 00086 if (hostname) 00087 free(hostname); 00088 hostname = rr_data; 00089 } 00090 00091 if (rr_class == C_IN && rr_type == T_CNAME) 00092 { 00093 /* Decode the RR data and replace ptrname with it. */ 00094 status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); 00095 if (status != ARES_SUCCESS) 00096 break; 00097 free(ptrname); 00098 ptrname = rr_data; 00099 } 00100 00101 free(rr_name); 00102 aptr += rr_len; 00103 if (aptr > abuf + alen) 00104 { 00105 status = ARES_EBADRESP; 00106 break; 00107 } 00108 } 00109 00110 if (status == ARES_SUCCESS && !hostname) 00111 status = ARES_ENODATA; 00112 if (status == ARES_SUCCESS) 00113 { 00114 /* We got our answer. Allocate memory to build the host entry. */ 00115 hostent = malloc(sizeof(struct hostent)); 00116 if (hostent) 00117 { 00118 hostent->h_addr_list = malloc(2 * sizeof(char *)); 00119 if (hostent->h_addr_list) 00120 { 00121 hostent->h_addr_list[0] = malloc(addrlen); 00122 if (hostent->h_addr_list[0]) 00123 { 00124 hostent->h_aliases = malloc(sizeof (char *)); 00125 if (hostent->h_aliases) 00126 { 00127 /* Fill in the hostent and return successfully. */ 00128 hostent->h_name = hostname; 00129 hostent->h_aliases[0] = NULL; 00130 hostent->h_addrtype = family; 00131 hostent->h_length = addrlen; 00132 memcpy(hostent->h_addr_list[0], addr, addrlen); 00133 hostent->h_addr_list[1] = NULL; 00134 *host = hostent; 00135 free(ptrname); 00136 return ARES_SUCCESS; 00137 } 00138 free(hostent->h_addr_list[0]); 00139 } 00140 free(hostent->h_addr_list); 00141 } 00142 free(hostent); 00143 } 00144 status = ARES_ENOMEM; 00145 } 00146 if (hostname) 00147 free(hostname); 00148 free(ptrname); 00149 return status; 00150 } |
Here is the call graph for this function:
|
Definition at line 46 of file ares_process.c. References ares_channel, process_timeouts(), read_tcp_data(), read_udp_packets(), time, and write_tcp_data(). Referenced by dns_client(), and gethostbynameaddr().
00047 { 00048 time_t now; 00049 00050 time(&now); 00051 write_tcp_data(channel, write_fds, now); 00052 read_tcp_data(channel, read_fds, now); 00053 read_udp_packets(channel, read_fds, now); 00054 process_timeouts(channel, now); 00055 } |
Here is the call graph for this function:
|
Definition at line 33 of file ares_query.c. References ares_callback, ares_channel, ARES_ENOMEM, ARES_FLAG_NORECURSE, ares_free_string(), ares_mkquery(), ares_send(), ARES_SUCCESS, callback(), ares_channeldata::flags, malloc, name, ares_channeldata::next_id, NULL, qcallback(), and status. Referenced by ares_search(), next_lookup(), and search_callback().
00035 { 00036 struct qquery *qquery; 00037 unsigned char *qbuf; 00038 int qlen, rd, status; 00039 00040 /* Compose the query. */ 00041 rd = !(channel->flags & ARES_FLAG_NORECURSE); 00042 status = ares_mkquery(name, dnsclass, type, channel->next_id, rd, &qbuf, 00043 &qlen); 00044 channel->next_id++; 00045 if (status != ARES_SUCCESS) 00046 { 00047 callback(arg, status, NULL, 0); 00048 return; 00049 } 00050 00051 /* Allocate and fill in the query structure. */ 00052 qquery = malloc(sizeof(struct qquery)); 00053 if (!qquery) 00054 { 00055 ares_free_string(qbuf); 00056 callback(arg, ARES_ENOMEM, NULL, 0); 00057 return; 00058 } 00059 qquery->callback = callback; 00060 qquery->arg = arg; 00061 00062 /* Send it off. qcallback will be called when we get an answer. */ 00063 ares_send(channel, qbuf, qlen, qcallback, qquery); 00064 ares_free_string(qbuf); 00065 } |
Here is the call graph for this function:
|
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:
|
Definition at line 26 of file ares_send.c. References ares__send_query(), ares_callback, ares_channel, ARES_EBADQUERY, ARES_ECONNREFUSED, ARES_ENOMEM, ARES_FLAG_USEVC, callback(), DNS_HEADER_QID, ares_channeldata::flags, free, HFIXEDSZ, malloc, ares_channeldata::nservers, NULL, PACKETSZ, ares_channeldata::queries, and time. Referenced by ares_query().
00028 { 00029 struct query *query; 00030 int i; 00031 time_t now; 00032 00033 /* Verify that the query is at least long enough to hold the header. */ 00034 if (qlen < HFIXEDSZ 00035 #ifndef LWIP 00036 || qlen >= (1 << 16) 00037 #endif 00038 ) 00039 { 00040 callback(arg, ARES_EBADQUERY, NULL, 0); 00041 return; 00042 } 00043 00044 /* Allocate space for query and allocated fields. */ 00045 query = malloc(sizeof(struct query)); 00046 if (!query) 00047 { 00048 callback(arg, ARES_ENOMEM, NULL, 0); 00049 return; 00050 } 00051 query->tcpbuf = malloc(qlen + 2); 00052 if (!query->tcpbuf) 00053 { 00054 free(query); 00055 callback(arg, ARES_ENOMEM, NULL, 0); 00056 return; 00057 } 00058 query->skip_server = malloc(channel->nservers * sizeof(int)); 00059 if (!query->skip_server) 00060 { 00061 free(query->tcpbuf); 00062 free(query); 00063 callback(arg, ARES_ENOMEM, NULL, 0); 00064 return; 00065 } 00066 00067 /* Compute the query ID. Start with no timeout. */ 00068 query->qid = DNS_HEADER_QID(qbuf); 00069 query->timeout = 0; 00070 00071 /* Form the TCP query buffer by prepending qlen (as two 00072 * network-order bytes) to qbuf. 00073 */ 00074 query->tcpbuf[0] = (qlen >> 8) & 0xff; 00075 query->tcpbuf[1] = qlen & 0xff; 00076 memcpy(query->tcpbuf + 2, qbuf, qlen); 00077 query->tcplen = qlen + 2; 00078 00079 /* Fill in query arguments. */ 00080 query->qbuf = query->tcpbuf + 2; 00081 query->qlen = qlen; 00082 query->callback = callback; 00083 query->arg = arg; 00084 00085 /* Initialize query status. */ 00086 query->try = 0; 00087 query->server = 0; 00088 for (i = 0; i < channel->nservers; i++) 00089 query->skip_server[i] = 0; 00090 query->using_tcp = (channel->flags & ARES_FLAG_USEVC) || qlen > PACKETSZ; 00091 query->error_status = ARES_ECONNREFUSED; 00092 00093 /* Chain the query into this channel's query list. */ 00094 query->next = channel->queries; 00095 channel->queries = query; 00096 00097 /* Perform the first query action. */ 00098 time(&now); 00099 ares__send_query(channel, query, now); 00100 } |
Here is the call graph for this function:
|
Definition at line 25 of file ares_strerror.c. Referenced by dns_client(), and dns_client_callback().
00026 { 00027 /* A future implementation may want to handle internationalization. 00028 * For now, just return a string literal from a table. 00029 */ 00030 const char *errtext[] = { 00031 "Successful completion", 00032 "DNS server returned answer with no data", 00033 "DNS server claims query was misformatted", 00034 "DNS server returned general failure", 00035 "Domain name not found", 00036 "DNS server does not implement requested operation", 00037 "DNS server refused query", 00038 "Misformatted DNS query", 00039 "Misformatted domain name", 00040 "Unsupported address family", 00041 "Misformatted DNS reply", 00042 "Could not contact DNS servers", 00043 "Timeout while contacting DNS servers", 00044 "End of file", 00045 "Error reading file", 00046 "Out of memory" 00047 }; 00048 00049 (void)memptr; 00050 00051 //#ifdef LWIP_ASSERT 00052 // LWIP_ASSERT("ares_strerror: code", code >= 0 && code < (sizeof(errtext) / sizeof(*errtext))); 00053 //#else 00054 // assert(code >= 0 && code < (sizeof(errtext) / sizeof(*errtext))); 00055 //#endif 00056 return errtext[code]; 00057 } |
|
Definition at line 25 of file ares_timeout.c. References ares_channel, query::next, ares_channeldata::queries, time, timeval::tv_sec, and timeval::tv_usec. Referenced by dns_client(), and gethostbynameaddr().
00027 { 00028 struct query *query; 00029 time_t now; 00030 int offset, min_offset; 00031 00032 /* No queries, no timeout (and no fetch of the current time). */ 00033 if (!channel->queries) 00034 return maxtv; 00035 00036 /* Find the minimum timeout for the current set of queries. */ 00037 time(&now); 00038 min_offset = -1; 00039 for (query = channel->queries; query; query = query->next) 00040 { 00041 if (query->timeout == 0) 00042 continue; 00043 offset = query->timeout - now; 00044 if (offset < 0) 00045 offset = 0; 00046 if (min_offset == -1 || offset < min_offset) 00047 min_offset = offset; 00048 } 00049 00050 /* If we found a minimum timeout and it's sooner than the one 00051 * specified in maxtv (if any), return it. Otherwise go with 00052 * maxtv. 00053 */ 00054 if (min_offset != -1 && (!maxtv || min_offset <= maxtv->tv_sec)) 00055 { 00056 tvbuf->tv_sec = min_offset; 00057 tvbuf->tv_usec = 0; 00058 return tvbuf; 00059 } 00060 else 00061 return maxtv; 00062 } |