vector<TSrvRecord> GetRecords(const string& host) const { ares_channel channel; int status; status = ares_init(&channel); if(status != ARES_SUCCESS) { throw UException(std::string("Failed to init ares channel: ") + ares_strerror(status)); } TCallbackInfo info; ares_query(channel, host.c_str(), ns_c_in, ns_t_srv, callback, &info); wait_ares(channel); ares_destroy(channel); if (info.Status != ARES_SUCCESS) { throw UException(std::string("Failed to make ares request: ") + ares_strerror(info.Status)); } struct ares_srv_reply* reply; status = ares_parse_srv_reply((const unsigned char*)info.Data.data(), info.Data.length(), &reply); if (info.Status != ARES_SUCCESS) { throw UException(std::string("Failed to parse response: ") + ares_strerror(status)); } vector<TSrvRecord> records; struct ares_srv_reply* next = reply; while (next != NULL) { TSrvRecord record; record.Host = next->host; record.Port = next->port; record.Priority = next->priority; record.Weight = next->weight; records.push_back(record); next = next->next; } ares_free_data(reply); return records; }
static void srv_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct mosquitto *mosq = arg; struct ares_srv_reply *reply = NULL; if(status == ARES_SUCCESS){ status = ares_parse_srv_reply(abuf, alen, &reply); if(status == ARES_SUCCESS){ // FIXME - choose which answer to use based on rfc2782 page 3. */ mosquitto_connect(mosq, reply->host, reply->port, mosq->keepalive); } }else{ _mosquitto_log_printf(mosq, MOSQ_LOG_ERR, "Error: SRV lookup failed (%d).", status); /* FIXME - calling on_disconnect here isn't correct. */ pthread_mutex_lock(&mosq->callback_mutex); if(mosq->on_disconnect){ mosq->in_callback = true; mosq->on_disconnect(mosq, mosq->userdata, 2); mosq->in_callback = false; } pthread_mutex_unlock(&mosq->callback_mutex); } }
static struct ph_dns_query_response *make_srv_resp(unsigned char *abuf, int alen) { struct ph_dns_query_response *resp; uint32_t size; struct ares_srv_reply *srv, *tmp; uint32_t nres = 0, i; if (ares_parse_srv_reply(abuf, alen, &srv) != ARES_SUCCESS) { return NULL; } for (nres = 0, tmp = srv; tmp; tmp = tmp->next) { nres++; } size = sizeof(*resp) + ((nres - 1) * sizeof(resp->answer[0])); resp = ph_mem_alloc_size(mt.aresp, size); if (!resp) { ares_free_data(srv); return NULL; } resp->num_answers = nres; for (tmp = srv, i = 0; tmp; tmp = tmp->next, i++) { resp->answer[i].name = ph_mem_strdup(mt.string, tmp->host); resp->answer[i].priority = tmp->priority; resp->answer[i].weight = tmp->weight; resp->answer[i].port = tmp->port; } // Sort in priority order qsort(resp->answer, nres, sizeof(resp->answer[0]), compare_mx_ent); ares_free_data(srv); return resp; }
static void query_srv_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct ares_srv_reply *srv_reply, *srv_ptr; PyObject *dns_result, *errorno, *tmp, *result, *callback; srv_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_srv_reply(answer_buf, answer_len, &srv_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 (srv_ptr = srv_reply; srv_ptr != NULL; srv_ptr = srv_ptr->next) { tmp = PyStructSequence_New(&AresQuerySRVResultType); if (tmp == NULL) { break; } PyStructSequence_SET_ITEM(tmp, 0, Py_BuildValue("s", srv_ptr->host)); PyStructSequence_SET_ITEM(tmp, 1, PyInt_FromLong((long)srv_ptr->port)); PyStructSequence_SET_ITEM(tmp, 2, PyInt_FromLong((long)srv_ptr->priority)); PyStructSequence_SET_ITEM(tmp, 3, PyInt_FromLong((long)srv_ptr->weight)); 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 (srv_reply) { ares_free_data(srv_reply); } Py_DECREF(callback); PyGILState_Release(gstate); }
static void query_srv_cb(void *arg, int status,int timeouts, unsigned char *answer_buf, int answer_len) { PyGILState_STATE gstate = PyGILState_Ensure(); int parse_status; struct ares_srv_reply *srv_reply, *srv_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_srv_reply(answer_buf, answer_len, &srv_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 (srv_ptr = srv_reply; srv_ptr != NULL; srv_ptr = srv_ptr->next) { tmp = PyTuple_New(4); if (tmp == NULL) { break; } PyTuple_SET_ITEM(tmp, 0, PyString_FromString(srv_ptr->host)); PyTuple_SET_ITEM(tmp, 1, PyInt_FromLong((long)srv_ptr->port)); PyTuple_SET_ITEM(tmp, 2, PyInt_FromLong((long)srv_ptr->priority)); PyTuple_SET_ITEM(tmp, 3, PyInt_FromLong((long)srv_ptr->weight)); PyList_Append(dns_result, tmp); Py_DECREF(tmp); } ares_free_data(srv_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); }