Example #1
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #6
0
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);
    }
}