X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdns.cpp;h=efb690dc248cd90f6eb0860c298d25b8ee6e7e4c;hb=1f1258997c2d63eb54c5addece622af37f637a7b;hp=04aa93b6cf452f205de0ee201adf69ec4617c162;hpb=8f31ffb7d0216f90d5fc51bb26ae9e238c34385b;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dns.cpp b/src/dns.cpp index 04aa93b6c..efb690dc2 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -36,9 +36,12 @@ using namespace std; #include #include #include "dns.h" +#include "inspircd.h" #include "helperfuncs.h" +#include "socketengine.h" -extern int statsAccept,statsRefused,statsUnknown,statsCollisions,statsDns,statsDnsGood,statsDnsBad,statsConnects,statsSent,statsRecv; +extern InspIRCd* ServerInstance; +extern ServerConfig* Config; #define max(a,b) (a > b ? a : b) #define DNS_MAX 8 /* max number of nameservers used */ @@ -152,10 +155,12 @@ void dns_empty_header(unsigned char *output, const s_header *header, const int l } void dns_close(int fd) { /* close query */ + log(DEBUG,"DNS: dns_close on fd %d",fd); if (fd == lastcreate) { wantclose = 1; return; } + shutdown(fd,2); close(fd); return; } @@ -246,6 +251,7 @@ static s_connection *dns_add_query(s_header *h) { /* build DNS query, add to lis s->fd = socket(PF_INET, SOCK_DGRAM, 0); if (s->fd != -1) { if (fcntl(s->fd, F_SETFL, O_NONBLOCK) != 0) { + shutdown(s->fd,2); close(s->fd); s->fd = -1; } @@ -257,6 +263,7 @@ static s_connection *dns_add_query(s_header *h) { /* build DNS query, add to lis addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; if (bind(s->fd,(sockaddr *)&addr,sizeof(addr)) != 0) { + shutdown(s->fd,2); close(s->fd); s->fd = -1; } @@ -270,6 +277,7 @@ static s_connection *dns_add_query(s_header *h) { /* build DNS query, add to lis connection_head = s; if (wantclose == 1) { + shutdown(lastcreate,2); close(lastcreate); wantclose = 0; } @@ -281,7 +289,7 @@ static int dns_build_query_payload(const char * const name, const unsigned short short payloadpos; const char * tempchr, * tempchr2; unsigned short l; - + payloadpos = 0; tempchr2 = name; @@ -408,12 +416,6 @@ char* DNS::dns_ntoa4(const in_addr * const ip) { /* numeric to ascii: convert 4p return dns_ntoa4_s(ip,r); } -char* DNS::dns_ntoa4_r(const in_addr *ip) { /* numeric to ascii (reentrant): convert 4part IP addr struct to new string */ - char *r; - r = new char[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; @@ -422,18 +424,8 @@ char* DNS::dns_ntoa4_s(const in_addr *ip, char *r) { /* numeric to ascii (buffer } char* DNS::dns_getresult(const int cfd) { /* retrieve result of DNS query */ - static char r[RESULTSIZE]; - return dns_getresult_s(cfd,r); -} - -char* DNS::dns_getresult_r(const int cfd) { /* retrieve result of DNS query (reentrant) */ - char *r; - r = new char[RESULTSIZE]; - if(dns_getresult_s(cfd,r) == NULL) { - delete r; - return NULL; - } - return r; + log(DEBUG,"DNS: dns_getresult with cfd=%d",cfd); + return dns_getresult_s(cfd,this->localbuf); } char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS query (buffered) */ @@ -458,6 +450,7 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS c = c->next; } if (c == NULL) { + log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d",cfd); return NULL; /* query not found */ } /* query found-- pull from list: */ @@ -474,22 +467,27 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS } 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 */ } 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) { /* no sense going on if we don't have any answers */ + log(DEBUG,"DNS: no answers!"); delete c; return NULL; } @@ -552,6 +550,7 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS switch (rr.type) { case DNS_QRY_PTR: + log(DEBUG,"DNS: got a result of type DNS_QRY_PTR"); o = 0; q = 0; while (q == 0 && i < l && o + 256 < 1023) { @@ -574,6 +573,7 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS res[o] = '\0'; 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) { @@ -622,6 +622,7 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS break; default: defaultcase: + log(DEBUG,"DNS: doing something with result 'default'"); memcpy(res,&h.payload[i],rr.rdlength); res[rr.rdlength] = '\0'; break; @@ -633,16 +634,19 @@ char* DNS::dns_getresult_s(const int cfd, char *res) { /* retrieve result of DNS DNS::DNS() { dns_init(); + log(DEBUG,"Create blank DNS"); } DNS::DNS(std::string dnsserver) { dns_init_2(dnsserver.c_str()); + log(DEBUG,"Create DNS"); } void DNS::SetNS(std::string dnsserver) { dns_init_2(dnsserver.c_str()); + log(DEBUG,"Set NS"); } DNS::~DNS() @@ -651,57 +655,80 @@ DNS::~DNS() bool DNS::ReverseLookup(std::string ip) { - statsDns++; + ServerInstance->stats->statsDns++; binip = dns_aton4(ip.c_str()); if (binip == NULL) { return false; } - this->fd = dns_getname4(binip); - if (this->fd == -1) + this->myfd = dns_getname4(binip); + if (this->myfd == -1) { return false; } + log(DEBUG,"DNS: ReverseLookup, fd=%d",this->myfd); +#ifndef THREADED_DNS + ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); +#endif return true; } bool DNS::ForwardLookup(std::string host) { - statsDns++; - this->fd = dns_getip4(host.c_str()); - if (this->fd == -1) + 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 + ServerInstance->SE->AddFd(this->myfd,true,X_ESTAB_DNS); +#endif 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->fd; + 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() { - return this->fd; + return this->myfd; } std::string DNS::GetResult() { - result = dns_getresult(this->fd); + log(DEBUG,"DNS: GetResult()"); + result = dns_getresult(this->myfd); +#ifndef THREADED_DNS + ServerInstance->SE->DelFd(this->myfd); +#endif if (result) { - statsDnsGood++; - dns_close(this->fd); + ServerInstance->stats->statsDnsGood++; + dns_close(this->myfd); return result; } else { - statsDnsBad++; - if (this->fd != -1) + ServerInstance->stats->statsDnsBad++; + if (this->myfd != -1) { - dns_close(this->fd); + dns_close(this->myfd); } return ""; } @@ -710,23 +737,72 @@ std::string DNS::GetResult() std::string DNS::GetResultIP() { char r[1024]; - result = dns_getresult(this->fd); - if (this->fd != -1) + log(DEBUG,"DNS: GetResultIP()"); + result = dns_getresult(this->myfd); + if (this->myfd != -1) { - dns_close(this->fd); +#ifndef THREADED_DNS + ServerInstance->SE->DelFd(this->myfd); +#endif + dns_close(this->myfd); } if (result) { - unsigned long oct1 = (unsigned)result[0]; - unsigned long oct2 = (unsigned)result[1]; - unsigned long oct3 = (unsigned)result[2]; - unsigned long oct4 = (unsigned)result[3]; - sprintf(r,"%lu.%lu.%lu.%lu",oct1,oct2,oct3,oct4); + 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 { + ServerInstance->stats->statsDnsBad++; log(DEBUG,"DANGER WILL ROBINSON! NXDOMAIN for forward lookup, but we got a reverse lookup!"); return ""; } } + + + +#ifdef THREADED_DNS +void* dns_task(void* arg) +{ + 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(u->ip)) + { + while (!dns1.HasResult()) + { + usleep(100); + } + host = dns1.GetResult(); + if (host != "") + { + if (dns2.ForwardLookup(host)) + { + while (!dns2.HasResult()) + { + usleep(100); + } + ip = dns2.GetResultIP(); + if (ip == std::string(u->ip)) + { + if (host.length() < 160) + { + strcpy(u->host,host.c_str()); + strcpy(u->dhost,host.c_str()); + } + } + } + } + } + u->dns_done = true; + return NULL; +} +#endif