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 void next_lookup(struct host_query *hquery) { int status; const char *p; struct hostent *host; for (p = hquery->remaining_lookups; *p; p++) { switch (*p) { case 'b': /* DNS lookup */ hquery->remaining_lookups = p + 1; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); return; case 'f': /* Host file lookup */ status = file_lookup(hquery->name, &host); if (status != ARES_ENOTFOUND) { end_hquery(hquery, status, host); return; } break; } } end_hquery(hquery, ARES_ENOTFOUND, NULL); }
void ph_dns_channel_query_raw( ph_dns_channel_t *chan, const char *name, int dnsclass, int type, ph_dns_channel_raw_query_func func, void *arg) { struct ph_dns_query *q; chan = fixup_chan(chan); q = ph_mem_alloc(mt.query); if (!q) { func(arg, ARES_ENOMEM, 0, NULL, 0); return; } q->chan = chan; q->arg = arg; q->qtype = PH_DNS_QUERY_NONE; q->func.raw = func; pthread_mutex_lock(&chan->chanlock); ares_search(chan->chan, name, dnsclass, type, result_cb, q); pthread_mutex_unlock(&chan->chanlock); }
static void next_lookup(struct host_query *hquery, int status_code) { const char *p; struct hostent *host; int status = status_code; for (p = hquery->remaining_lookups; *p; p++) { switch (*p) { case 'b': /* DNS lookup */ hquery->remaining_lookups = p + 1; if ((hquery->want_family == AF_INET6) || (hquery->want_family == AF_UNSPEC)) { /* if inet6 or unspec, start out with AAAA */ hquery->sent_family = AF_INET6; ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback, hquery); } else { hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } return; case 'f': /* Host file lookup */ status = file_lookup(hquery->name, hquery->want_family, &host); /* this status check below previously checked for !ARES_ENOTFOUND, but we should not assume that this single error code is the one that can occur, as that is in fact no longer the case */ if (status == ARES_SUCCESS) { end_hquery(hquery, status, host); return; } status = status_code; /* Use original status code */ break; } } end_hquery(hquery, status, NULL); }
int mosquitto_connect_srv(struct mosquitto *mosq, const char *host, int keepalive, const char *bind_address) { #ifdef WITH_SRV char *h; int rc; if(!mosq) return MOSQ_ERR_INVAL; rc = ares_init(&mosq->achan); if(rc != ARES_SUCCESS){ return MOSQ_ERR_UNKNOWN; } if(!host){ // get local domain }else{ #ifdef WITH_TLS if(mosq->tls_cafile || mosq->tls_capath || mosq->tls_psk){ h = _mosquitto_malloc(strlen(host) + strlen("_secure-mqtt._tcp.") + 1); if(!h) return MOSQ_ERR_NOMEM; sprintf(h, "_secure-mqtt._tcp.%s", host); }else{ #endif h = _mosquitto_malloc(strlen(host) + strlen("_mqtt._tcp.") + 1); if(!h) return MOSQ_ERR_NOMEM; sprintf(h, "_mqtt._tcp.%s", host); #ifdef WITH_TLS } #endif ares_search(mosq->achan, h, ns_c_in, ns_t_srv, srv_callback, mosq); _mosquitto_free(h); } pthread_mutex_lock(&mosq->state_mutex); mosq->state = mosq_cs_connect_srv; pthread_mutex_unlock(&mosq->state_mutex); mosq->keepalive = keepalive; return MOSQ_ERR_SUCCESS; #else return MOSQ_ERR_NOT_SUPPORTED; #endif }
void ph_dns_channel_query( ph_dns_channel_t *chan, const char *name, int query_type, ph_dns_channel_query_func func, void *arg) { struct ph_dns_query *q; int dnsclass = ns_c_in, type; chan = fixup_chan(chan); q = ph_mem_alloc(mt.query); if (!q) { func(arg, ARES_ENOMEM, 0, NULL, 0, NULL); return; } q->chan = chan; q->arg = arg; q->qtype = query_type; q->func.func = func; switch (query_type) { case PH_DNS_QUERY_A: type = ns_t_a; break; case PH_DNS_QUERY_AAAA: type = ns_t_aaaa; break; case PH_DNS_QUERY_SRV: type = ns_t_srv; break; case PH_DNS_QUERY_MX: type = ns_t_mx; break; default: ph_panic("invalid query type %d", query_type); } pthread_mutex_lock(&chan->chanlock); ares_search(chan->chan, name, dnsclass, type, result_cb, q); pthread_mutex_unlock(&chan->chanlock); }
void LLAres::search(const std::string &query, LLResType type, QueryResponder *resp) { ares_search(chan_, query.c_str(), ns_c_in, type, search_callback, new LLPointer<QueryResponder>(resp)); }