Пример #1
0
 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;
 }
Пример #2
0
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);
	}
}
Пример #3
0
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);
}
Пример #5
0
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);
}