00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ares_private.h"
00024 #include "ares_dns.h"
00025
00026 struct qquery {
00027 ares_callback callback;
00028 void *arg;
00029 };
00030
00031 static void qcallback(void *arg, int status, unsigned char *abuf, int alen);
00032
00033 void ares_query(ares_channel channel, const char *name, int dnsclass,
00034 int type, ares_callback callback, void *arg)
00035 {
00036 struct qquery *qquery;
00037 unsigned char *qbuf;
00038 int qlen, rd, status;
00039
00040
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
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
00063 ares_send(channel, qbuf, qlen, qcallback, qquery);
00064 ares_free_string(qbuf);
00065 }
00066
00067 static void qcallback(void *arg, int status, unsigned char *abuf, int alen)
00068 {
00069 struct qquery *qquery = (struct qquery *) arg;
00070 unsigned int ancount;
00071 int rcode;
00072
00073 if (status != ARES_SUCCESS)
00074 qquery->callback(qquery->arg, status, abuf, alen);
00075 else
00076 {
00077
00078 rcode = DNS_HEADER_RCODE(abuf);
00079 ancount = DNS_HEADER_ANCOUNT(abuf);
00080
00081
00082 switch (rcode)
00083 {
00084 case NOERROR:
00085 status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA;
00086 break;
00087 case FORMERR:
00088 status = ARES_EFORMERR;
00089 break;
00090 case SERVFAIL:
00091 status = ARES_ESERVFAIL;
00092 break;
00093 case NXDOMAIN:
00094 status = ARES_ENOTFOUND;
00095 break;
00096 case NOTIMP:
00097 status = ARES_ENOTIMP;
00098 break;
00099 case REFUSED:
00100 status = ARES_EREFUSED;
00101 break;
00102 }
00103 qquery->callback(qquery->arg, status, abuf, alen);
00104 }
00105 free(qquery);
00106 }