static struct ph_dns_query_response *make_mx_resp(unsigned char *abuf, int alen) { struct ph_dns_query_response *resp; uint32_t size; struct ares_mx_reply *mx, *tmp; uint32_t nmxs = 0, i; if (ares_parse_mx_reply(abuf, alen, &mx) != ARES_SUCCESS) { return NULL; } for (nmxs = 0, tmp = mx; tmp; tmp = tmp->next) { nmxs++; } size = sizeof(*resp) + ((nmxs - 1) * sizeof(resp->answer[0])); resp = ph_mem_alloc_size(mt.aresp, size); if (!resp) { ares_free_data(mx); return NULL; } resp->num_answers = nmxs; for (tmp = mx, i = 0; tmp; tmp = tmp->next, i++) { resp->answer[i].name = ph_mem_strdup(mt.string, tmp->host); resp->answer[i].priority = tmp->priority; } // Sort in priority order qsort(resp->answer, nmxs, sizeof(resp->answer[0]), compare_mx_ent); ares_free_data(mx); return resp; }
static void query_mx_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct ares_mx_reply *mx_reply, *mx_ptr; PyObject *dns_result, *errorno, *tmp, *result, *callback; mx_reply = NULL; 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_mx_reply(answer_buf, answer_len, &mx_reply); 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; } for (mx_ptr = mx_reply; mx_ptr != NULL; mx_ptr = mx_ptr->next) { tmp = PyStructSequence_New(&AresQueryMXResultType); if (tmp == NULL) { break; } PyStructSequence_SET_ITEM(tmp, 0, Py_BuildValue("s", mx_ptr->host)); PyStructSequence_SET_ITEM(tmp, 1, PyInt_FromLong((long)mx_ptr->priority)); 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 (mx_reply) { ares_free_data(mx_reply); } Py_DECREF(callback); PyGILState_Release(gstate); }
static void query_mx_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct ares_mx_reply *mx_reply, *mx_ptr; 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_mx_reply(answer_buf, answer_len, &mx_reply); 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; } for (mx_ptr = mx_reply; mx_ptr != NULL; mx_ptr = mx_ptr->next) { tmp = PyTuple_New(2); if (tmp == NULL) { break; } PyTuple_SET_ITEM(tmp, 0, PyString_FromString(mx_ptr->host)); PyTuple_SET_ITEM(tmp, 1, PyInt_FromLong((long)mx_ptr->priority)); PyList_Append(dns_result, tmp); Py_DECREF(tmp); } ares_free_data(mx_reply); 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); }