X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdns.cpp;h=69df48cc65acdeba1d9e000b0ab6f9e275624adb;hb=a5c99b8dc6164ca3a9abed1c843627c1e817caaa;hp=df7ee26940d6c78b662cbd12c093e2f3e7a12b76;hpb=4f03923da6de7a586d0f0b76a06cc79be0b9eabe;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dns.cpp b/src/dns.cpp index df7ee2694..69df48cc6 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -3,13 +3,13 @@ * +------------------------------------+ * * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. - * E-mail: - * - * + * E-mail: + * + * * * Written by Craig Edwards, Craig McLure, and others. * This program is free but copyrighted software; see - * the file COPYING for details. + * the file COPYING for details. * * --------------------------------------------------- */ @@ -49,12 +49,14 @@ using namespace std; #include "dns.h" #include "inspircd.h" #include "helperfuncs.h" +#include "inspircd_config.h" #include "socketengine.h" #include "configreader.h" extern InspIRCd* ServerInstance; extern ServerConfig* Config; extern time_t TIME; +extern userrec* fd_ref_table[MAX_DESCRIPTORS]; enum QueryType { DNS_QRY_A = 1, DNS_QRY_PTR = 12 }; enum QueryFlags1 { FLAGS1_MASK_RD = 0x01, FLAGS1_MASK_TC = 0x02, FLAGS1_MASK_AA = 0x04, FLAGS1_MASK_OPCODE = 0x78, FLAGS1_MASK_QR = 0x80 }; @@ -64,25 +66,13 @@ class s_connection; typedef std::map connlist; typedef connlist::iterator connlist_iter; -connlist connections; - -Resolver* dns_classes[MAX_DESCRIPTORS]; -struct in_addr servers4[8]; -int i4; -int initdone = 0; -int wantclose = 0; -int lastcreate = -1; +DNS* Res = NULL; -class s_connection -{ - public: - unsigned char id[2]; - unsigned int _class; - QueryType type; - int want_list; - int fd; -}; +connlist connections; +int master_socket = -1; +Resolver* dns_classes[65536]; +insp_inaddr myserver; class s_rr_middle { @@ -106,6 +96,24 @@ class s_header unsigned char payload[512]; }; +class s_connection +{ + public: + unsigned char id[2]; + unsigned char res[512]; + unsigned int _class; + QueryType type; + + s_connection() + { + *res = 0; + } + + unsigned char* result_ready(s_header &h, int length); + int send_requests(const s_header *h, const int l, QueryType qt); +}; + + void *dns_align(void *inp) { @@ -162,98 +170,43 @@ inline void dns_empty_header(unsigned char *output, const s_header *header, cons memcpy(&output[12],header->payload,l); } -void dns_close(int fd) -{ -#ifndef THREADED_DNS - if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->DelFd(fd); -#endif - log(DEBUG,"DNS: dns_close on fd %d",fd); - if (fd == lastcreate) - { - wantclose = 1; - return; - } - shutdown(fd,2); - close(fd); - return; -} - -void DNS::dns_init() -{ - FILE *f; - int i; - in_addr addr4; - char buf[1024]; - if (initdone == 1) - return; - i4 = 0; - - initdone = 1; - srand((unsigned int) TIME); - memset(servers4,'\0',sizeof(in_addr) * 8); - f = fopen("/etc/resolv.conf","r"); - if (f == NULL) - return; - while (fgets(buf,1024,f) != NULL) { - if (strncmp(buf,"nameserver",10) == 0) - { - i = 10; - while (buf[i] == ' ' || buf[i] == '\t') - i++; - if (i4 < 8) - { - if (dns_aton4_s(&buf[i],&addr4) != NULL) - memcpy(&servers4[i4++],&addr4,sizeof(in_addr)); - } - } - } - fclose(f); -} - -void DNS::dns_init_2(const char* dnsserver) -{ - in_addr addr4; - i4 = 0; - srand((unsigned int) TIME); - memset(servers4,'\0',sizeof(in_addr) * 8); - if (dns_aton4_s(dnsserver,&addr4) != NULL) - memcpy(&servers4[i4++],&addr4,sizeof(in_addr)); -} - -int dns_send_requests(const s_header *h, const s_connection *s, const int l) +int s_connection::send_requests(const s_header *h, const int l, QueryType qt) { - int i; - sockaddr_in addr4; + insp_sockaddr addr; unsigned char payload[sizeof(s_header)]; + this->_class = 1; + this->type = qt; + dns_empty_header(payload,h,l); - - i = 0; - - /* otherwise send via standard ipv4 boringness */ - memset(&addr4,0,sizeof(addr4)); - memcpy(&addr4.sin_addr,&servers4[i],sizeof(addr4.sin_addr)); - addr4.sin_family = AF_INET; - addr4.sin_port = htons(53); - if (sendto(s->fd, payload, l + 12, 0, (sockaddr *) &addr4, sizeof(addr4)) == -1) + memset(&addr,0,sizeof(addr)); +#ifdef IPV6 + memcpy(&addr.sin6_addr,&myserver,sizeof(addr.sin6_addr)); + addr.sin6_family = AF_FAMILY; + addr.sin6_port = htons(53); +#else + memcpy(&addr.sin_addr.s_addr,&myserver,sizeof(addr.sin_addr)); + addr.sin_family = AF_FAMILY; + addr.sin_port = htons(53); +#endif + if (sendto(master_socket, payload, l + 12, 0, (sockaddr *) &addr, sizeof(addr)) == -1) { + log(DEBUG,"Error in sendto!"); return -1; } return 0; } -s_connection *dns_add_query(s_header *h) +s_connection* dns_add_query(s_header *h, int &id) { - s_connection * s = new s_connection; - int id = rand() % 65536; + id = rand() % 65536; + s_connection * s = new s_connection(); - /* set header flags */ - h->id[0] = s->id[0] = id >> 8; /* verified by dns_getresult_s() */ + h->id[0] = s->id[0] = id >> 8; h->id[1] = s->id[1] = id & 0xFF; h->flags1 = 0 | FLAGS1_MASK_RD; h->flags2 = 0; @@ -261,48 +214,63 @@ s_connection *dns_add_query(s_header *h) h->ancount = 0; h->nscount = 0; h->arcount = 0; - s->want_list = 0; - s->fd = socket(PF_INET, SOCK_DGRAM, 0); - if (s->fd != -1) + + if (connections.find(id) == connections.end()) + connections[id] = s; + return s; +} + +void create_socket() +{ + log(DEBUG,"---- BEGIN DNS INITIALIZATION, SERVER=%s ---",Config->DNSServer); + insp_inaddr addr; + srand((unsigned int) TIME); + memset(&myserver,0,sizeof(insp_inaddr)); + if (insp_aton(Config->DNSServer,&addr) > 0) + memcpy(&myserver,&addr,sizeof(insp_inaddr)); + + master_socket = socket(PF_PROTOCOL, SOCK_DGRAM, 0); + if (master_socket != -1) { - if (fcntl(s->fd, F_SETFL, O_NONBLOCK) != 0) + log(DEBUG,"Set query socket nonblock"); + if (fcntl(master_socket, F_SETFL, O_NONBLOCK) != 0) { - shutdown(s->fd,2); - close(s->fd); - s->fd = -1; + shutdown(master_socket,2); + close(master_socket); + master_socket = -1; } } - if (s->fd != -1) + if (master_socket != -1) { - sockaddr_in addr; +#ifdef IPV6 + insp_sockaddr addr; memset(&addr,0,sizeof(addr)); - addr.sin_family = AF_INET; + addr.sin6_family = AF_FAMILY; + addr.sin6_port = 0; + memset(&addr.sin6_addr,255,sizeof(in6_addr)); +#else + insp_sockaddr addr; + memset(&addr,0,sizeof(addr)); + addr.sin_family = AF_FAMILY; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; - if (bind(s->fd,(sockaddr *)&addr,sizeof(addr)) != 0) +#endif + log(DEBUG,"Binding query port"); + if (bind(master_socket,(sockaddr *)&addr,sizeof(addr)) != 0) { - shutdown(s->fd,2); - close(s->fd); - s->fd = -1; + log(DEBUG,"Cant bind with source port = 0"); + shutdown(master_socket,2); + close(master_socket); + master_socket = -1; } - } - if (s->fd == -1) - { - DELETE(s); - return NULL; - } - /* create new connection object, add to linked list */ - if (connections.find(s->fd) == connections.end()) - connections[s->fd] = s; - if (wantclose == 1) - { - shutdown(lastcreate,2); - close(lastcreate); - wantclose = 0; + if (master_socket >= 0) + { + log(DEBUG,"Attach query port to socket engine"); + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->AddFd(master_socket,true,X_ESTAB_DNS); + } } - lastcreate = s->fd; - return s; } int dns_build_query_payload(const char * const name, const unsigned short rr, const unsigned short _class, unsigned char * const payload) @@ -344,182 +312,147 @@ int dns_build_query_payload(const char * const name, const unsigned short rr, co return payloadpos + 4; } -in_addr* DNS::dns_aton4(const char * const ipstring) +int DNS::dns_getip4(const char *name) { - static in_addr ip; - return dns_aton4_s(ipstring,&ip); -} - -in_addr* DNS::dns_aton4_r(const char *ipstring) { /* ascii to numeric (reentrant): convert string to new 4part IP addr struct */ - in_addr* ip; - ip = new in_addr; - if(dns_aton4_s(ipstring,ip) == NULL) - { - DELETE(ip); - return NULL; - } - return ip; -} - -in_addr* DNS::dns_aton4_s(const char *ipstring, in_addr *ip) { /* ascii to numeric (buffered): convert string to given 4part IP addr struct */ - inet_aton(ipstring,ip); - return ip; -} - -int DNS::dns_getip4(const char *name) { /* build, add and send A query; retrieve result with dns_getresult() */ + /* build, add and send A query; retrieve result with dns_getresult() */ s_header h; - s_connection *s; - int l; - - dns_init(); + s_connection* req; + int id; - - l = dns_build_query_payload(name,DNS_QRY_A,1,(unsigned char *)&h.payload); - if (l == -1) + int length = dns_build_query_payload(name,DNS_QRY_A,1,(unsigned char*)&h.payload); + if (length == -1) return -1; - s = dns_add_query(&h); - if (s == NULL) - return -1; - s->_class = 1; - s->type = DNS_QRY_A; - if (dns_send_requests(&h,s,l) == -1) + req = dns_add_query(&h, id); + if (req == NULL) return -1; - return s->fd; -} - -int DNS::dns_getip4list(const char *name) { /* build, add and send A query; retrieve result with dns_getresult() */ - s_header h; - s_connection *s; - int l; - - dns_init(); - - l = dns_build_query_payload(name,DNS_QRY_A,1,(unsigned char *)&h.payload); - if (l == -1) - return -1; - s = dns_add_query(&h); - if (s == NULL) - return -1; - s->_class = 1; - s->type = DNS_QRY_A; - s->want_list = 1; - if (dns_send_requests(&h,s,l) == -1) + if (req->send_requests(&h,length,DNS_QRY_A) == -1) return -1; - return s->fd; + return id; } -int DNS::dns_getname4(const in_addr *ip) { /* build, add and send PTR query; retrieve result with dns_getresult() */ +int DNS::dns_getname4(const insp_inaddr *ip) +{ /* build, add and send PTR query; retrieve result with dns_getresult() */ +#ifdef IPV6 + return -1; +#else + log(DEBUG,"DNS::dns_getname4"); char query[512]; s_header h; - s_connection * s; + s_connection* req; unsigned char *c; - int l; + int id; c = (unsigned char *)&ip->s_addr; sprintf(query,"%d.%d.%d.%d.in-addr.arpa",c[3],c[2],c[1],c[0]); - l = dns_build_query_payload(query,DNS_QRY_PTR,1,(unsigned char *)&h.payload); - if (l == -1) + int length = dns_build_query_payload(query,DNS_QRY_PTR,1,(unsigned char*)&h.payload); + if (length == -1) return -1; - s = dns_add_query(&h); - if (s == NULL) + req = dns_add_query(&h, id); + if (req == NULL) return -1; - s->_class = 1; - s->type = DNS_QRY_PTR; - if (dns_send_requests(&h,s,l) == -1) + if (req->send_requests(&h,length,DNS_QRY_PTR) == -1) return -1; - return s->fd; -} - -char* DNS::dns_ntoa4(const in_addr * const ip) { /* numeric to ascii: convert 4part IP addr struct to static string */ - static char r[256]; - return dns_ntoa4_s(ip,r); -} - -char* DNS::dns_ntoa4_s(const in_addr *ip, char *r) { /* numeric to ascii (buffered): convert 4part IP addr struct to given string */ - unsigned char *m; - m = (unsigned char *)&ip->s_addr; - sprintf(r,"%d.%d.%d.%d",m[0],m[1],m[2],m[3]); - return r; -} - -char* DNS::dns_getresult(const int cfd) { /* retrieve result of DNS query */ - log(DEBUG,"DNS: dns_getresult with cfd=%d",cfd); - return dns_getresult_s(cfd,this->localbuf); + return id; +#endif } -char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS query (buffered) */ +/* Return the next id which is ready, and the result attached to it + */ +DNSResult DNS::dns_getresult() +{ + /* retrieve result of DNS query (buffered) */ s_header h; s_connection *c; - int l, i, q, curanswer, o; - s_rr_middle rr; + int length; unsigned char buffer[sizeof(s_header)]; - unsigned short p; - if (res) - *res = 0; + length = recv(master_socket,buffer,sizeof(s_header),0); + + if (length < 12) + return std::make_pair(-1,""); + + dns_fill_header(&h,buffer,length - 12); - /* FireDNS used a linked list for this. How ugly (and slow). */ - connlist_iter n_iter = connections.find(cfd); - if (n_iter == connections.end()) + // Get the id of this request + unsigned long this_id = h.id[1] + (h.id[0] << 8); + + // Do we have a pending request for it? + + connlist_iter n_iter = connections.find(this_id); + if (n_iter == connections.end()) + { + log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d queryid=%d",master_socket,this_id); + return std::make_pair(-1,""); + } + else + { + /* Remove the query from the list */ + c = (s_connection*)n_iter->second; + /* We don't delete c here, because its done later when needed */ + connections.erase(n_iter); + } + unsigned char* a = c->result_ready(h, length); + std::string resultstr; + + if (a == NULL) { - log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d",cfd); - return NULL; + resultstr = ""; } else { - /* Remove the query from the list */ - c = (s_connection*)n_iter->second; - /* We don't delete c here, because its done later when needed */ - connections.erase(n_iter); + if (c->type == DNS_QRY_A) + { + char formatted[1024]; + snprintf(formatted,1024,"%u.%u.%u.%u",a[0],a[1],a[2],a[3]); + resultstr = std::string(formatted); + } + else + { + resultstr = std::string((const char*)a); + } } - l = recv(c->fd,buffer,sizeof(s_header),0); - dns_close(c->fd); - if (l < 12) - { - DELETE(c); - return NULL; - } - dns_fill_header(&h,buffer,l - 12); - if (c->id[0] != h.id[0] || c->id[1] != h.id[1]) - { - log(DEBUG,"DNS: id mismatch on query"); - DELETE(c); - return NULL; /* ID mismatch */ - } + delete c; + return std::make_pair(this_id,resultstr); +} + +/** A result is ready, process it + */ +unsigned char* s_connection::result_ready(s_header &h, int length) +{ + int i, q, curanswer, o; + s_rr_middle rr; + unsigned short p; + if ((h.flags1 & FLAGS1_MASK_QR) == 0) { log(DEBUG,"DNS: didnt get a query result"); - DELETE(c); return NULL; } if ((h.flags1 & FLAGS1_MASK_OPCODE) != 0) { log(DEBUG,"DNS: got an OPCODE and didnt want one"); - DELETE(c); return NULL; } if ((h.flags2 & FLAGS2_MASK_RCODE) != 0) { log(DEBUG,"DNS lookup failed due to SERVFAIL"); - DELETE(c); return NULL; } if (h.ancount < 1) { log(DEBUG,"DNS: no answers!"); - DELETE(c); return NULL; } i = 0; q = 0; - l -= 12; - while ((unsigned)q < h.qdcount && i < l) + length -= 12; + while ((unsigned)q < h.qdcount && i < length) { if (h.payload[i] > 63) { @@ -540,7 +473,7 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS while ((unsigned)curanswer < h.ancount) { q = 0; - while (q == 0 && i < l) + while (q == 0 && i < length) { if (h.payload[i] > 63) { @@ -557,20 +490,19 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS else i += h.payload[i] + 1; /* skip length and label */ } } - if (l - i < 10) + if (length - i < 10) { - DELETE(c); return NULL; } dns_fill_rr(&rr,&h.payload[i]); i += 10; - if (rr.type != c->type) + if (rr.type != this->type) { curanswer++; i += rr.rdlength; continue; } - if (rr._class != c->_class) + if (rr._class != this->_class) { curanswer++; i += rr.rdlength; @@ -578,9 +510,9 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS } break; } - if ((unsigned)curanswer == h.ancount) + if ((unsigned int)curanswer == h.ancount) return NULL; - if ((unsigned)i + rr.rdlength > (unsigned)l) + if (i + rr.rdlength > (unsigned int)length) return NULL; if (rr.rdlength > 1023) return NULL; @@ -591,9 +523,8 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS log(DEBUG,"DNS: got a result of type DNS_QRY_PTR"); o = 0; q = 0; - while (q == 0 && i < l && o + 256 < 1023) + while (q == 0 && i < length && o + 256 < 1023) { - log(DEBUG,"DNS: loop 1"); if (h.payload[i] > 63) { log(DEBUG,"DNS: h.payload[i] > 63"); @@ -608,7 +539,6 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS } else { - log(DEBUG,"Loop 2: res='%s'",res); res[o] = '\0'; if (o != 0) res[o++] = '.'; @@ -619,60 +549,9 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS } } res[o] = '\0'; - log(DEBUG,"DNS: res='%s'",res); break; case DNS_QRY_A: log(DEBUG,"DNS: got a result of type DNS_QRY_A"); - if (c->want_list) - { - dns_ip4list *alist = (dns_ip4list *) res; /* we have to trust that this is aligned */ - while ((char *)alist - (char *)res < 700) - { - if (rr.type != DNS_QRY_A) - break; - if (rr._class != 1) - break; - if (rr.rdlength != 4) - { - DELETE(c); - return NULL; - } - memcpy(&alist->ip,&h.payload[i],4); - if ((unsigned)++curanswer >= h.ancount) - break; - i += rr.rdlength; - q = 0; - while (q == 0 && i < l) - { - if (h.payload[i] > 63) - { - i += 2; - q = 1; - } - else - { - if (h.payload[i] == 0) - { - i++; - q = 1; - } - else i += h.payload[i] + 1; - } - } - if (l - i < 10) - { - DELETE(c); - return NULL; - } - dns_fill_rr(&rr,&h.payload[i]); - i += 10; - alist->next = (dns_ip4list *) dns_align(((char *) alist) + sizeof(dns_ip4list)); - alist = alist->next; - alist->next = NULL; - } - alist->next = NULL; - break; - } memcpy(res,&h.payload[i],rr.rdlength); res[rr.rdlength] = '\0'; break; @@ -681,320 +560,112 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS res[rr.rdlength] = '\0'; break; } - DELETE(c); return res; } DNS::DNS() { - dns_init(); log(DEBUG,"Create blank DNS"); } -DNS::DNS(const std::string &dnsserver) -{ - dns_init_2(dnsserver.c_str()); - log(DEBUG,"Create DNS with server '%s'",dnsserver.c_str()); -} - -void DNS::SetNS(const std::string &dnsserver) -{ - dns_init_2(dnsserver.c_str()); - log(DEBUG,"Set NS"); -} - DNS::~DNS() { } -bool DNS::ReverseLookup(const std::string &ip, bool ins) -{ - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDns++; - binip = dns_aton4(ip.c_str()); - if (binip == NULL) - { - return false; - } - - this->myfd = dns_getname4(binip); - if (this->myfd == -1) - { - return false; - } - log(DEBUG,"DNS: ReverseLookup, fd=%d",this->myfd); -#ifndef THREADED_DNS - if (ins) - { - if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); - } -#endif - return true; -} - -bool DNS::ForwardLookup(const std::string &host, bool ins) -{ - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDns++; - this->myfd = dns_getip4(host.c_str()); - if (this->myfd == -1) - { - return false; - } - log(DEBUG,"DNS: ForwardLookup, fd=%d",this->myfd); -#ifndef THREADED_DNS - if (ins) - { - if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); - } -#endif - return true; -} - -bool DNS::ForwardLookupWithFD(const std::string &host, int &fd) -{ - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDns++; - this->myfd = dns_getip4(host.c_str()); - fd = this->myfd; - if (this->myfd == -1) - { - return false; - } - log(DEBUG,"DNS: ForwardLookupWithFD, fd=%d",this->myfd); - if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_MODULE); - return true; -} - -bool DNS::HasResult(int fd) -{ - return (fd == this->myfd); -} - -/* Only the multithreaded dns uses this poll() based - * check now. As its in another thread we dont have - * to worry about its performance that much. - */ -bool DNS::HasResult() -{ - log(DEBUG,"DNS: HasResult, fd=%d",this->myfd); - pollfd polls; - polls.fd = this->myfd; - polls.events = POLLIN; - int ret = poll(&polls,1,1); - log(DEBUG,"DNS: Hasresult returning %d",ret); - return (ret > 0); -} - -int DNS::GetFD() +Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd(forward) { - return this->myfd; -} - -std::string DNS::GetResult() -{ - log(DEBUG,"DNS: GetResult()"); - result = dns_getresult(this->myfd); - if (result) + if (forward) { - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDnsGood++; - dns_close(this->myfd); - return result; + log(DEBUG,"Resolver: Forward lookup on %s",source.c_str()); + this->myid = Res->dns_getip4(source.c_str()); } else { - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDnsBad++; - if (this->myfd != -1) + log(DEBUG,"Resolver: Reverse lookup on %s",source.c_str()); + insp_inaddr binip; + if (insp_aton(source.c_str(), &binip) > 0) { - dns_close(this->myfd); + /* Valid ip address */ + this->myid = Res->dns_getname4(&binip); } - return ""; } -} - -std::string DNS::GetResultIP() -{ - char r[1024]; - log(DEBUG,"DNS: GetResultIP()"); - result = dns_getresult(this->myfd); - if (this->myfd != -1) - { - dns_close(this->myfd); - } - if (result) - { - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDnsGood++; - unsigned char a = (unsigned)result[0]; - unsigned char b = (unsigned)result[1]; - unsigned char c = (unsigned)result[2]; - unsigned char d = (unsigned)result[3]; - snprintf(r,1024,"%u.%u.%u.%u",a,b,c,d); - return r; - } - else + if (this->myid == -1) { - if (ServerInstance && ServerInstance->stats) - ServerInstance->stats->statsDnsBad++; - log(DEBUG,"DANGER WILL ROBINSON! NXDOMAIN for forward lookup, but we got a reverse lookup!"); - return ""; + log(DEBUG,"Resolver::Resolver: Could not get an id!"); + this->OnError(RESOLVER_NSDOWN); + throw ModuleException("Resolver: Couldnt get an id to make a request"); + /* We shouldnt get here really */ + return; } -} - + log(DEBUG,"Resolver::Resolver: this->myid=%d",this->myid); +} -#ifdef THREADED_DNS -void* dns_task(void* arg) +void Resolver::OnLookupComplete(const std::string &result) { - userrec* u = (userrec*)arg; - log(DEBUG,"DNS thread for user %s",u->nick); - DNS dns1; - DNS dns2; - std::string host; - std::string ip; - if (dns1.ReverseLookup((char*)inet_ntoa(u->ip4))) - { - while (!dns1.HasResult()) - { - usleep(100); - } - host = dns1.GetResult(); - if (host != "") - { - if (dns2.ForwardLookup(host), false) - { - while (!dns2.HasResult()) - { - usleep(100); - } - ip = dns2.GetResultIP(); - if (ip == std::string((char*)inet_ntoa(u->ip4))) - { - if (host.length() < 160) - { - strcpy(u->host,host.c_str()); - strcpy(u->dhost,host.c_str()); - } - } - } - } - } - u->dns_done = true; - return NULL; } -#endif -Resolver::Resolver(const std::string &source, bool forward, const std::string &dnsserver = "") : input(source), fwd(forward), server(dnsserver) +void Resolver::OnError(ResolverError e) { - if (this->server != "") - Query.SetNS(this->server); - else - Query.SetNS(Config->DNSServer); - - if (forward) - { - Query.ForwardLookup(input.c_str(), false); - this->fd = Query.GetFD(); - } - else - { - Query.ReverseLookup(input.c_str(), false); - this->fd = Query.GetFD(); - } - if (fd < 0) - { - log(DEBUG,"Resolver::Resolver: RESOLVER_NSDOWN"); - this->OnError(RESOLVER_NSDOWN); - ModuleException e("Resolver: Nameserver is down"); - throw e; - /* We shouldnt get here really */ - return; - } - - if (ServerInstance && ServerInstance->SE) - { - log(DEBUG,"Resolver::Resolver: this->fd=%d",this->fd); - ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_CLASSDNS); - } - else - { - log(DEBUG,"Resolver::Resolver: RESOLVER_NOTREADY"); - this->OnError(RESOLVER_NOTREADY); - ModuleException e("Resolver: Core not initialized yet"); - throw e; - /* We shouldnt get here really */ - return; - } } Resolver::~Resolver() { log(DEBUG,"Resolver::~Resolver"); - if (ServerInstance && ServerInstance->SE) - ServerInstance->SE->DelFd(this->fd); } -int Resolver::GetFd() +int Resolver::GetId() { - return this->fd; + return this->myid; } -bool Resolver::ProcessResult() +bool Resolver::ProcessResult(const std::string &result) { log(DEBUG,"Resolver::ProcessResult"); - if (this->fwd) - result = Query.GetResultIP(); - else - result = Query.GetResult(); - if (result != "") - { - log(DEBUG,"Resolver::OnLookupComplete(%s)",result.c_str()); - this->OnLookupComplete(result); - return true; - } - else + if (!result.length()) { log(DEBUG,"Resolver::OnError(RESOLVER_NXDOMAIN)"); this->OnError(RESOLVER_NXDOMAIN); return false; } -} - -void Resolver::OnLookupComplete(const std::string &result) -{ -} + else + { -void Resolver::OnError(ResolverError e) -{ + log(DEBUG,"Resolver::OnLookupComplete(%s)",result.c_str()); + this->OnLookupComplete(result); + return true; + } } void dns_deal_with_classes(int fd) { log(DEBUG,"dns_deal_with_classes(%d)",fd); - if ((fd > -1) && (dns_classes[fd])) + if (fd == master_socket) { - log(DEBUG,"Valid fd %d",fd); - dns_classes[fd]->ProcessResult(); - delete dns_classes[fd]; - dns_classes[fd] = NULL; + DNSResult res = Res->dns_getresult(); + if (res.first != -1) + { + log(DEBUG,"Result available, id=%d",res.first); + if (dns_classes[res.first]) + { + dns_classes[res.first]->ProcessResult(res.second); + delete dns_classes[res.first]; + dns_classes[res.first] = NULL; + } + } } } bool dns_add_class(Resolver* r) { log(DEBUG,"dns_add_class"); - if ((r) && (r->GetFd() > -1)) + if ((r) && (r->GetId() > -1)) { - if (!dns_classes[r->GetFd()]) + if (!dns_classes[r->GetId()]) { log(DEBUG,"dns_add_class: added class"); - dns_classes[r->GetFd()] = r; + dns_classes[r->GetId()] = r; return true; } else @@ -1013,6 +684,8 @@ bool dns_add_class(Resolver* r) void init_dns() { + Res = new DNS(); memset(dns_classes,0,sizeof(dns_classes)); + create_socket(); }