#include "ctdl_module.h"
#include "event_client.h"
+int DebugCAres = 0;
extern struct ev_loop *event_base;
struct hostent *hostent)
{
AsyncIO *IO = data;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
EV_DNS_LOGT_STOP(DNS.timeout);
-#endif
ev_timer_stop (event_base, &IO->DNS.timeout);
IO->DNS.Query->DNSStatus = status;
static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct hostent* host;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ struct hostent* host = NULL;
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
NULL,
NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (host != NULL)
+ ares_free_hostent(host);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct hostent* host;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ struct hostent* host = NULL;
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
NULL,
NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (host != NULL)
+ ares_free_hostent(host);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct hostent* host;
+ struct hostent* host = NULL;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
NULL,
NULL);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (host != NULL)
+ ares_free_hostent(host);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct ares_mx_reply *mx_out;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ struct ares_mx_reply *mx_out = NULL;
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->DNSStatus = ares_parse_mx_reply(abuf, alen, &mx_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (mx_out != NULL)
+ ares_free_data(mx_out);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct hostent* host;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ struct hostent* host = NULL;
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->DNSStatus = ares_parse_ns_reply(abuf, alen, &host);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (host != NULL)
+ ares_free_hostent(host);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen)
{
- struct ares_srv_reply *srv_out;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ struct ares_srv_reply *srv_out = NULL;
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->DNSStatus = ares_parse_srv_reply(abuf, alen, &srv_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (srv_out != NULL)
+ ares_free_data(srv_out);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
static void ParseAnswerTXT(AsyncIO *IO, unsigned char* abuf, int alen)
{
struct ares_txt_reply *txt_out;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
if (IO->DNS.Query->VParsedDNSReply != NULL)
IO->DNS.Query->DNSReplyFree(IO->DNS.Query->VParsedDNSReply);
IO->DNS.Query->DNSStatus = ares_parse_txt_reply(abuf, alen, &txt_out);
if (IO->DNS.Query->DNSStatus != ARES_SUCCESS) {
+ if (txt_out != NULL)
+ ares_free_data(txt_out);
StrBufPlain(IO->ErrMsg,
ares_strerror(IO->DNS.Query->DNSStatus), -1);
return;
int alen)
{
AsyncIO *IO = arg;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
+ SetEVState(IO, eCaresStart);
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
EV_DNS_LOGT_STOP(DNS.timeout);
-#endif
ev_timer_stop (event_base, &IO->DNS.timeout);
IO->DNS.Query->DNSStatus = status;
if (status == ARES_SUCCESS)
IO->DNS.Query->DNS_CB(arg, abuf, alen);
else {
- EV_syslog(LOG_DEBUG, "C-ARES: Failed by: %s error %s\n",
- __FUNCTION__,
- ares_strerror(status));
- StrBufPlain(IO->ErrMsg, ares_strerror(status), -1);
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: Failed by: %s error %s\n",
+ __FUNCTION__,
+ ares_strerror(status));
+ StrBufPrintf(IO->ErrMsg,
+ "%s-lookup %s - %s",
+ IO->DNS.Query->QueryTYPE,
+ (IO->DNS.Query->QStr != NULL)? IO->DNS.Query->QStr : "",
+ ares_strerror(status));
IO->DNS.Query->DNSStatus = status;
}
void QueryCbDone(AsyncIO *IO)
{
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+ SetEVState(IO, eCaresDoneIO);
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
EV_DNS_LOGT_STOP(DNS.timeout);
-#endif
+ ev_timer_stop (event_base, &IO->DNS.timeout);
+ EV_DNS_LOGT_STOP(unwind_stack);
ev_idle_stop(event_base, &IO->unwind_stack);
}
void DestructCAres(AsyncIO *IO)
{
+ SetEVState(IO, eCaresX);
+ EVNC_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
+ EVNC_syslog(LOG_DEBUG, "C-ARES: - stopping %s %d %p \n", "DNS.recv_event", IO->DNS.recv_event.fd, &IO->DNS.recv_event);
+ ev_io_stop(event_base, &IO->DNS.recv_event);
+
+ EVNC_syslog(LOG_DEBUG, "C-ARES: - stopping %s %d %p\n", "DNS.send_event", IO->DNS.send_event.fd, &IO->DNS.send_event);
+ ev_io_stop(event_base, &IO->DNS.send_event);
+
+ EVNC_syslog(LOG_DEBUG, "C-ARES: - stopping %s %p\n", "DNS.timeout", &IO->DNS.send_event);
+ ev_timer_stop (event_base, &IO->DNS.timeout);
+
+ EVNC_syslog(LOG_DEBUG, "C-ARES: - stopping %s %p\n", "DNS.unwind_stack", &IO->unwind_stack);
+ ev_idle_stop(event_base, &IO->unwind_stack);
ares_destroy_options(&IO->DNS.Options);
}
void InitC_ares_dns(AsyncIO *IO)
{
int optmask = 0;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s %p\n", __FUNCTION__, IO->DNS.Channel);
-#endif
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s %p\n", __FUNCTION__, IO->DNS.Channel);
if (IO->DNS.Channel == NULL) {
optmask |= ARES_OPT_SOCK_STATE_CB;
(NextTV->tv_usec != MaxTV.tv_usec))
{
fd_set readers, writers;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s Timeout!\n", __FUNCTION__);
-#endif
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s Timeout!\n", __FUNCTION__);
+
FD_ZERO(&readers);
FD_ZERO(&writers);
ares_fds(IO->DNS.Channel, &readers, &writers);
struct hostent *hostent)
{
AsyncIO *IO = (AsyncIO *) Ctx;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
IO->DNS.Query->DNSStatus = status;
IO->DNS.Query->VParsedDNSReply = hostent;
IO->DNS.Query->DNSReplyFree = (FreeDNSReply) ares_free_hostent;
+ EV_DNS_LOGT_STOP(DNS.timeout);
+ ev_timer_stop (event_base, &IO->DNS.timeout);
+
ev_idle_init(&IO->unwind_stack,
IO_postdns_callback);
IO->unwind_stack.data = IO;
EV_DNS_LOGT_INIT(unwind_stack);
EV_DNS_LOGT_START(unwind_stack);
ev_idle_start(event_base, &IO->unwind_stack);
+
}
void QueueGetHostByName(AsyncIO *IO,
DNSQueryParts *QueryParts,
IO_CallBack PostDNS)
{
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
IO->DNS.SourcePort = 0;
-#endif
IO->DNS.Query = QueryParts;
IO->DNS.Query->PostDNS = PostDNS;
}
+const char* QT[] = {
+ "A",
+ "AAAA",
+ "MX",
+ "NS",
+ "TXT",
+ "SRV",
+ "CNAME",
+ "PTR"
+};
+
int QueueQuery(ns_type Type,
const char *name,
AsyncIO *IO,
int length, family;
char address_b[sizeof(struct in6_addr)];
-#ifdef DEBUG_CARES
IO->DNS.SourcePort = 0;
-#endif
IO->DNS.Query = QueryParts;
IO->DNS.Query->PostDNS = PostDNS;
+ IO->DNS.Start = IO->Now;
+ IO->DNS.Query->QStr = name;
InitC_ares_dns(IO);
switch(Type) {
case ns_t_a:
IO->DNS.Query->DNS_CB = ParseAnswerA;
+ IO->DNS.Query->QueryTYPE = QT[0];
break;
case ns_t_aaaa:
IO->DNS.Query->DNS_CB = ParseAnswerAAAA;
+ IO->DNS.Query->QueryTYPE = QT[1];
break;
case ns_t_mx:
IO->DNS.Query->DNS_CB = ParseAnswerMX;
+ IO->DNS.Query->QueryTYPE = QT[2];
break;
case ns_t_ns:
IO->DNS.Query->DNS_CB = ParseAnswerNS;
+ IO->DNS.Query->QueryTYPE = QT[3];
break;
case ns_t_txt:
IO->DNS.Query->DNS_CB = ParseAnswerTXT;
+ IO->DNS.Query->QueryTYPE = QT[4];
break;
case ns_t_srv:
IO->DNS.Query->DNS_CB = ParseAnswerSRV;
+ IO->DNS.Query->QueryTYPE = QT[5];
break;
case ns_t_cname:
IO->DNS.Query->DNS_CB = ParseAnswerCNAME;
+ IO->DNS.Query->QueryTYPE = QT[6];
break;
case ns_t_ptr:
-
-
+ IO->DNS.Query->QueryTYPE = QT[7];
if (inet_pton(AF_INET, name, &address_b) == 1) {
length = sizeof(struct in_addr);
family = AF_INET;
IO);
EV_DNS_LOGT_START(DNS.timeout);
ev_timer_start(event_base, &IO->DNS.timeout);
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s X1\n", __FUNCTION__);
-#endif
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s X1\n", __FUNCTION__);
+
return 1;
default:
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %sX2\n", __FUNCTION__);
-#endif
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %sX2\n", __FUNCTION__);
return 0;
}
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
+
ares_query(IO->DNS.Channel, name, ns_c_in, Type, QueryCb, IO);
EV_DNS_LOGT_START(DNS.timeout);
ev_timer_start(event_base, &IO->DNS.timeout);
{
AsyncIO *IO = watcher->data;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ IO->Now = ev_now(event_base);
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
ares_process_fd(IO->DNS.Channel,
ARES_SOCKET_BAD,
{
AsyncIO *IO = watcher->data;
-#ifdef DEBUG_CARES
- EV_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
-#endif
+ IO->Now = ev_now(event_base);
+
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s\n", __FUNCTION__);
ares_process_fd(IO->DNS.Channel,
IO->DNS.recv_event.fd,
{
AsyncIO *IO = data;
/* already inside of the event queue. */
-#ifdef DEBUG_CARES
-{
- struct sockaddr_in sin = {};
- socklen_t slen;
- slen = sizeof(sin);
- if ((IO->DNS.SourcePort == 0) &&
- (getsockname(sock, &sin, &slen) == 0))
+ if (DebugCAres)
{
- IO->DNS.SourcePort = ntohs(sin.sin_port);
+ struct sockaddr_in sin = {};
+ socklen_t slen;
+ slen = sizeof(sin);
+ if ((IO->DNS.SourcePort == 0) &&
+ (getsockname(sock, &sin, &slen) == 0))
+ {
+ IO->DNS.SourcePort = ntohs(sin.sin_port);
+ }
+ EV_DNS_syslog(LOG_DEBUG, "C-ARES: %s %d|%d Sock %d port %hu\n",
+ __FUNCTION__,
+ read,
+ write,
+ sock,
+ IO->DNS.SourcePort);
}
- EV_syslog(LOG_DEBUG, "C-ARES: %s %d|%d Sock %d port %hu\n",
- __FUNCTION__,
- read,
- write,
- sock,
- IO->DNS.SourcePort);
-}
-#endif
+
+ IO->Now = ev_now(event_base);
if (read) {
if ((IO->DNS.recv_event.fd != sock) &&
ev_io_stop(event_base, &IO->DNS.send_event);
}
}
+void EnableDebugCAres(const int n)
+{
+ DebugCAres = n;
+}
CTDL_MODULE_INIT(c_ares_client)
{
if (!threading)
{
+ CtdlRegisterDebugFlagHook(HKEY("cares"), EnableDebugCAres, &DebugCAres);
int r = ares_library_init(ARES_LIB_INIT_ALL);
if (0 != r) {