X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmodules%2Fc-ares-dns%2Fserv_c-ares-dns.c;h=8878f995f67d63a3fbe0d95866388c75a87472d1;hb=8a42ffd1e764e16f783fa8a995ee42536b9c156f;hp=e945ccf9f785da5f30de87acbc23942e8a31cd49;hpb=1965fe005619a4a759f23253408cfc3ec9a3ebd2;p=citadel.git diff --git a/citadel/modules/c-ares-dns/serv_c-ares-dns.c b/citadel/modules/c-ares-dns/serv_c-ares-dns.c index e945ccf9f..8878f995f 100644 --- a/citadel/modules/c-ares-dns/serv_c-ares-dns.c +++ b/citadel/modules/c-ares-dns/serv_c-ares-dns.c @@ -1,19 +1,19 @@ /* - * Copyright (c) 1998-2009 by the citadel.org team + * Copyright (c) 1998-2012 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. + * This program is open source software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3. + * + * * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * + * * * Inspired by NodeJS.org; thanks for the MX-Parser ;-) */ @@ -57,6 +57,7 @@ #include "ctdl_module.h" #include "event_client.h" +int DebugCAres = 0; extern struct ev_loop *event_base; @@ -69,10 +70,10 @@ static void HostByAddrCb(void *data, 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; @@ -85,10 +86,9 @@ static void HostByAddrCb(void *data, 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); @@ -100,6 +100,8 @@ static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -111,10 +113,9 @@ static void ParseAnswerA(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -126,6 +127,8 @@ static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -137,11 +140,9 @@ static void ParseAnswerAAAA(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -153,6 +154,8 @@ static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -166,10 +169,9 @@ static void ParseAnswerCNAME(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -177,6 +179,8 @@ static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -189,10 +193,9 @@ static void ParseAnswerMX(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -200,6 +203,8 @@ static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -211,10 +216,9 @@ static void ParseAnswerNS(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -222,6 +226,8 @@ static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -235,9 +241,8 @@ static void ParseAnswerSRV(AsyncIO *IO, unsigned char* abuf, int alen) 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); @@ -245,6 +250,8 @@ static void ParseAnswerTXT(AsyncIO *IO, unsigned char* abuf, int alen) 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; @@ -260,19 +267,19 @@ void QueryCb(void *arg, int alen) { AsyncIO *IO = arg; -#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; 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)); + EV_DNS_syslog(LOG_DEBUG, "C-ARES: Failed by: %s error %s\n", + __FUNCTION__, + ares_strerror(status)); StrBufPlain(IO->ErrMsg, ares_strerror(status), -1); IO->DNS.Query->DNSStatus = status; } @@ -287,16 +294,30 @@ void QueryCb(void *arg, void QueryCbDone(AsyncIO *IO) { -#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); + EV_DNS_LOGT_STOP(unwind_stack); ev_idle_stop(event_base, &IO->unwind_stack); } void DestructCAres(AsyncIO *IO) { + 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); } @@ -304,9 +325,8 @@ void DestructCAres(AsyncIO *IO) 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; @@ -333,9 +353,8 @@ DNStimeouttrigger_callback(struct ev_loop *loop, ev_timer *watcher, int revents) (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); @@ -349,20 +368,24 @@ void QueueGetHostByNameDone(void *Ctx, 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, @@ -370,10 +393,9 @@ 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; @@ -402,12 +424,11 @@ int QueueQuery(ns_type Type, 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; InitC_ares_dns(IO); @@ -465,20 +486,18 @@ int QueueQuery(ns_type Type, 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); @@ -496,9 +515,9 @@ static void DNS_send_callback(struct ev_loop *loop, ev_io *watcher, int revents) { 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, @@ -508,9 +527,9 @@ static void DNS_recv_callback(struct ev_loop *loop, ev_io *watcher, int revents) { 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, @@ -521,24 +540,25 @@ void SockStateCb(void *data, int sock, int read, int write) { 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) && @@ -579,11 +599,16 @@ void SockStateCb(void *data, int sock, int read, int write) 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) {