static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct host_query *hquery = (struct host_query *) arg; ares_channel channel = hquery->channel; struct hostent *host = NULL; hquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (hquery->sent_family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); } else if (hquery->sent_family == AF_INET6) { status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if ((status == ARES_ENODATA || status == ARES_EBADRESP) && hquery->want_family == AF_UNSPEC) { /* The query returned something but either there were no AAAA records (e.g. just CNAME) or the response was malformed. Try looking up A instead. */ hquery->sent_family = AF_INET
static void query_cname_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct hostent *hostent = NULL; PyObject *dns_result, *errorno, *tmp, *result, *callback; callback = (PyObject *)arg; ASSERT(callback); if (status != ARES_SUCCESS) { errorno = PyInt_FromLong((long)status); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } parse_status = ares_parse_a_reply(answer_buf, answer_len, &hostent, NULL, NULL); if (parse_status != ARES_SUCCESS) { errorno = PyInt_FromLong((long)parse_status); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } dns_result = PyList_New(0); if (!dns_result) { PyErr_NoMemory(); PyErr_WriteUnraisable(Py_None); errorno = PyInt_FromLong((long)ARES_ENOMEM); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } tmp = Py_BuildValue("s", hostent->h_name); PyList_Append(dns_result, tmp); Py_DECREF(tmp); errorno = Py_None; Py_INCREF(Py_None); callback: result = PyObject_CallFunctionObjArgs(callback, dns_result, errorno, NULL); if (result == NULL) { PyErr_WriteUnraisable(callback); } Py_XDECREF(result); Py_DECREF(dns_result); Py_DECREF(errorno); if (hostent) { ares_free_hostent(hostent); } Py_DECREF(callback); PyGILState_Release(gstate); }
static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct host_query *hquery = (struct host_query *) arg; ares_channel channel = hquery->channel; struct hostent *host = NULL; hquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (hquery->sent_family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); } else if (hquery->sent_family == AF_INET6) { status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if ((status == ARES_ENODATA || status == ARES_EBADRESP || (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL)) && hquery->want_family == AF_UNSPEC) { /* The query returned something but either there were no AAAA records (e.g. just CNAME) or the response was malformed. Try looking up A instead. */ if (host) ares_free_hostent(host); hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); return; } if (host && channel->nsort) sort6_addresses(host, channel->sortlist, channel->nsort); } end_hquery(hquery, status, host); } else if ((status == ARES_ENODATA || status == ARES_EBADRESP || status == ARES_ETIMEOUT) && (hquery->sent_family == AF_INET6 && hquery->want_family == AF_UNSPEC)) { /* The AAAA query yielded no useful result. Now look up an A instead. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } else if (status == ARES_EDESTRUCTION) end_hquery(hquery, status, NULL); else next_lookup(hquery, status); }
static struct ph_dns_query_response *make_a_resp(unsigned char *abuf, int alen) { int ancount = DNS_HEADER_ANCOUNT(abuf); struct ph_dns_query_response *resp; uint32_t size; struct ares_addrttl *ttls = NULL; int res; struct hostent *host; int nttls; int i; char *name; ttls = malloc(ancount * sizeof(*ttls)); if (!ttls) { return NULL; } nttls = ancount; res = ares_parse_a_reply(abuf, alen, &host, ttls, &nttls); if (res) { free(ttls); return NULL; } size = sizeof(*resp) + ((nttls - 1) * sizeof(resp->answer[0])); resp = ph_mem_alloc_size(mt.aresp, size + strlen(host->h_name) + 1); if (!resp) { free(ttls); return NULL; } // this is where we'll stash the name name = ((char*)resp) + size; strcpy(name, host->h_name); resp->num_answers = ancount; resp->name = name; for (i = 0; i < nttls; i++) { resp->answer[i].name = name; resp->answer[i].ttl = ttls[i].ttl; resp->answer[i].addr.family = AF_INET; resp->answer[i].addr.sa.v4.sin_family = AF_INET; resp->answer[i].addr.sa.v4.sin_addr = ttls[i].ipaddr; } free(ttls); ares_free_hostent(host); return resp; }
static void host_callback(void *arg, int status, unsigned char *abuf, int alen) { struct host_query *hquery = (struct host_query *) arg; ares_channel channel = hquery->channel; struct hostent *host; if (status == ARES_SUCCESS) { status = ares_parse_a_reply(abuf, alen, &host); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); end_hquery(hquery, status, host); } else if (status == ARES_EDESTRUCTION) end_hquery(hquery, status, NULL); else next_lookup(hquery); }
static void query_cname_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct hostent *hostent; ares_cb_data_t *data; DNSResolver *self; PyObject *dns_result, *errorno, *tmp, *result, *callback; ASSERT(arg); data = (ares_cb_data_t*)arg; self = data->resolver; callback = data->cb; ASSERT(self); /* Object could go out of scope in the callback, increase refcount to avoid it */ Py_INCREF(self); if (status != ARES_SUCCESS) { errorno = PyInt_FromLong((long)status); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } parse_status = ares_parse_a_reply(answer_buf, answer_len, &hostent, NULL, NULL); if (parse_status != ARES_SUCCESS) { errorno = PyInt_FromLong((long)parse_status); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } dns_result = PyList_New(1); if (!dns_result) { PyErr_NoMemory(); PyErr_WriteUnraisable(Py_None); errorno = PyInt_FromLong((long)ARES_ENOMEM); dns_result = Py_None; Py_INCREF(Py_None); goto callback; } tmp = PyString_FromString(hostent->h_name); PyList_Append(dns_result, tmp); Py_DECREF(tmp); ares_free_hostent(hostent); errorno = Py_None; Py_INCREF(Py_None); callback: result = PyObject_CallFunctionObjArgs(callback, self, dns_result, errorno, NULL); if (result == NULL) { PyErr_WriteUnraisable(callback); } Py_XDECREF(result); Py_DECREF(callback); PyMem_Free(data); Py_DECREF(self); PyGILState_Release(gstate); }
void cares_callback_req(void *argdata, int status, int timeouts, unsigned char *abuf, int alen) { UNUSED_ARGUMENT(timeouts); struct hostent *hostptr = NULL; int is_a_reply = 0; int nttl, cnt = 0; int i; struct ares_addrttl *ttls = (struct ares_addrttl*) nkn_malloc_type(sizeof(struct ares_addrttl) * nkn_max_domain_ips, mod_auth_addrttl); struct ares_addr6ttl *ttls6 = (struct ares_addr6ttl*) nkn_malloc_type(sizeof(struct ares_addr6ttl) * nkn_max_domain_ips, mod_auth_addr6ttl); if (http_cfg_fo_use_dns) nttl = nkn_max_domain_ips; else nttl = 1; auth_dns_t* pdns = (auth_dns_t*)(((auth_msg_t*)(argdata))->authdata); if (pdns == NULL) { DBG_LOG(ERROR, MOD_AUTHMGR, "invalid pdns entry"); free(ttls); free(ttls6); return; } pdns->resolved = 0; if(status != ARES_SUCCESS) { ip_addr_t ip; ip.addr.v4.s_addr = INADDR_NONE; ip.family = AF_INET; memcpy(&pdns->ip[0], &ip, sizeof(ip_addr_t)); pdns->ttl[0] = DEFAULT_DNS_ERR_TTL; //nvsd defaults pdns->num_ips = 1; DBG_LOG(ERROR, MOD_AUTHMGR, "Dnslookup for domain:%s failed:%s", pdns->domain, ares_strerror(status)); AO_fetch_and_add1(&glob_dns_task_failed); AO_fetch_and_add1(&glob_dns_task_completed); free(ttls); free(ttls6); } else { if (pdns->ip[0].family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &hostptr, ttls, &nttl); is_a_reply = 1; } else { status = ares_parse_aaaa_reply(abuf, alen, &hostptr, ttls6, &nttl); } if (status != ARES_SUCCESS || !hostptr) { ip_addr_t ip; ip.addr.v4.s_addr = INADDR_NONE; ip.family = AF_INET; memcpy(&pdns->ip[0], &ip, sizeof(ip_addr_t)); pdns->ttl[0] = DEFAULT_DNS_ERR_TTL; //nvsd defaults pdns->num_ips = 1; DBG_LOG(ERROR, MOD_AUTHMGR, "Dnslookup for domain:%s failed:%s in parsing ", pdns->domain,ares_strerror(status)); AO_fetch_and_add1(&glob_dns_task_failed); AO_fetch_and_add1(&glob_dns_task_completed); free(ttls); free(ttls6); } else { for (i=0, cnt=nttl-1; i<nttl && cnt>=0; i++, cnt--) { /* multiple RR are given and we are chosing only * the first one, so ttls[0].ipaddr will also provide * the ip, memcopy not needed, its just assignment*/ if (hostptr->h_length > (int)sizeof(struct in6_addr)) { DBG_LOG(ERROR, MOD_AUTHMGR, "incorrect host->h_length"); } else { if (is_a_reply) { memcpy(&(pdns->ip[i].addr.v4.s_addr), &ttls[cnt].ipaddr.s_addr, sizeof(in_addr_t)); pdns->ip[i].family = AF_INET; //apply nvsd default if something is wrong pdns->ttl[i] = (ttls[cnt].ttl<0)? DEFAULT_DNS_TTL:ttls[cnt].ttl; } else { memcpy(&(pdns->ip[i].addr.v6), &ttls6[cnt].ip6addr, sizeof(struct in6_addr)); pdns->ip[i].family = AF_INET6; //apply nvsd default if something is wrong pdns->ttl[i] = (ttls6[cnt].ttl<0)? DEFAULT_DNS_TTL:ttls6[cnt].ttl; } if (is_loopback(&(pdns->ip[i])) == 0) { pdns->resolved = 1; } } } pdns->num_ips = nttl; AO_fetch_and_add1(&glob_dns_task_completed); //free ares memory ares_free_hostent(hostptr); free(ttls); free(ttls6); } } /* Negative hashing, forcing a failure in find_origin_server*/ dns_hash_and_insert((char*)pdns->domain, &pdns->ip[0], &pdns->ttl[0], pdns->resolved, pdns->num_ips); nkn_task_set_action_and_state((nkn_task_id_t)(pdns->auth_task_id), TASK_ACTION_OUTPUT, TASK_STATE_RUNNABLE); if (enable_reinit && (status == ARES_ESERVFAIL)) { /* * something is wrong here. BIND9 servers do not respond to this * channel after encountering this error, so reset everything */ channel_ready = 0; AO_fetch_and_add1(&glob_dns_servfail); } }