X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdns.cpp;h=461722b29dba2e7539bd864a8b09d73968c69ca8;hb=551d687ec6d7ce44be35fae0dd7345fe73c4f63a;hp=58cbcca76647e4c8bd8593020a9f2a180d11127d;hpb=2f8303334f2c5a62bcce47d39e8cf41208a9a296;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dns.cpp b/src/dns.cpp index 58cbcca76..461722b29 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -1,16 +1,27 @@ -/* +------------------------------------+ - * | Inspire Internet Relay Chat Daemon | - * +------------------------------------+ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2012 William Pitcock + * Copyright (C) 2009-2010 Daniel De Graaf + * Copyright (C) 2006, 2009 Robin Burchell + * Copyright (C) 2007, 2009 Dennis Friis + * Copyright (C) 2008 Thomas Stagner + * Copyright (C) 2005-2007 Craig Edwards * - * InspIRCd: (C) 2002-2010 InspIRCd Development Team - * See: http://wiki.inspircd.org/Credits + * This file is part of InspIRCd. InspIRCd 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, version 2. * - * This program is free but copyrighted software; see - * the file COPYING for details. + * 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, see . */ + /* $Core */ /* @@ -23,7 +34,7 @@ Please do not assume that firedns works like this, looks like this, walks like this or tastes like this. */ -#ifndef WIN32 +#ifndef _WIN32 #include #include #include @@ -223,7 +234,7 @@ inline void DNS::EmptyHeader(unsigned char *output, const DNSHeader *header, con /** Send requests we have previously built down the UDP socket */ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryType qt) { - ServerInstance->Logs->Log("RESOLVER", DEBUG,"DNSRequest::SendRequests"); + ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG,"DNSRequest::SendRequests"); unsigned char payload[sizeof(DNSHeader)]; @@ -235,7 +246,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp if (ServerInstance->SE->SendTo(dnsobj, payload, length + 12, 0, &(dnsobj->myserver.sa), sa_size(dnsobj->myserver)) != length+12) return -1; - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Sent OK"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Sent OK"); return 0; } @@ -247,8 +258,28 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id, const char* original) return NULL; /* Create an id */ + unsigned int tries = 0; do { id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID); + if (++tries == DNS::MAX_REQUEST_ID*5) + { + // If we couldn't find an empty slot this many times, do a sequential scan as a last + // resort. If an empty slot is found that way, go on, otherwise throw an exception + id = -1; + for (int i = 0; i < DNS::MAX_REQUEST_ID; i++) + { + if (!requests[i]) + { + id = i; + break; + } + } + + if (id == -1) + throw ModuleException("DNS: All ids are in use"); + + break; + } } while (requests[id]); DNSRequest* req = new DNSRequest(this, id, original); @@ -331,14 +362,14 @@ void DNS::Rehash() if (ServerInstance->SE->Bind(this->GetFd(), bindto) < 0) { /* Failed to bind */ - ServerInstance->Logs->Log("RESOLVER",SPARSE,"Error binding dns socket - hostnames will NOT resolve"); + ServerInstance->Logs->Log("RESOLVER",LOG_SPARSE,"Error binding dns socket - hostnames will NOT resolve"); ServerInstance->SE->Shutdown(this, 2); ServerInstance->SE->Close(this); this->SetFd(-1); } else if (!ServerInstance->SE->AddFd(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE)) { - ServerInstance->Logs->Log("RESOLVER",SPARSE,"Internal error starting DNS - hostnames will NOT resolve."); + ServerInstance->Logs->Log("RESOLVER",LOG_SPARSE,"Internal error starting DNS - hostnames will NOT resolve."); ServerInstance->SE->Shutdown(this, 2); ServerInstance->SE->Close(this); this->SetFd(-1); @@ -346,24 +377,20 @@ void DNS::Rehash() } else { - ServerInstance->Logs->Log("RESOLVER",SPARSE,"Error creating DNS socket - hostnames will NOT resolve"); + ServerInstance->Logs->Log("RESOLVER",LOG_SPARSE,"Error creating DNS socket - hostnames will NOT resolve"); } } /** Initialise the DNS UDP socket so that we can send requests */ DNS::DNS() { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::DNS"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::DNS"); /* Clear the Resolver class table */ memset(Classes,0,sizeof(Classes)); /* Clear the requests class table */ memset(requests,0,sizeof(requests)); - /* Set the id of the next request to 0 - */ - currid = 0; - /* DNS::Rehash() sets this to a valid ptr */ this->cache = NULL; @@ -490,7 +517,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp) } else { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::GetNameForce IPv6 bad format for '%s'", ip); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::GetNameForce IPv6 bad format for '%s'", ip); /* Invalid IP address */ return -1; } @@ -505,7 +532,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp) } else { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::GetNameForce IPv4 bad format for '%s'", ip); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::GetNameForce IPv4 bad format for '%s'", ip); /* Invalid IP address */ return -1; } @@ -514,7 +541,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp) length = this->MakePayload(query, DNS_QUERY_PTR, 1, (unsigned char*)&h.payload); if (length == -1) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::GetNameForce can't query '%s' using '%s' because it's too long", ip, query); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::GetNameForce can't query '%s' using '%s' because it's too long", ip, query); return -1; } @@ -522,13 +549,13 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp) if (!req) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::GetNameForce can't add query (resolver down?)"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::GetNameForce can't add query (resolver down?)"); return -1; } if (req->SendRequests(&h, length, DNS_QUERY_PTR) == -1) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS::GetNameForce can't send (firewall?)"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS::GetNameForce can't send (firewall?)"); return -1; } @@ -569,7 +596,7 @@ DNSResult DNS::GetResult() /* Did we get the whole header? */ if (length < 12) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"GetResult didn't get a full packet (len=%d)", length); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"GetResult didn't get a full packet (len=%d)", length); /* Nope - something screwed up. */ return DNSResult(-1,"",0,""); } @@ -585,8 +612,10 @@ DNSResult DNS::GetResult() */ if (from != myserver) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Got a result from the wrong server! Bad NAT or DNS forging attempt? '%s' != '%s'", - from.str().c_str(), myserver.str().c_str()); + std::string server1 = from.str(); + std::string server2 = myserver.str(); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Got a result from the wrong server! Bad NAT or DNS forging attempt? '%s' != '%s'", + server1.c_str(), server2.c_str()); return DNSResult(-1,"",0,""); } @@ -603,7 +632,7 @@ DNSResult DNS::GetResult() if (!requests[this_id]) { /* Somehow we got a DNS response for a request we never made... */ - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Hmm, got a result that we didn't ask for (id=%lx). Ignoring.", this_id); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Hmm, got a result that we didn't ask for (id=%lx). Ignoring.", this_id); return DNSResult(-1,"",0,""); } else @@ -767,7 +796,7 @@ DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, unsigned length) DNS::FillResourceRecord(&rr,&header.payload[i]); i += 10; - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Resolver: rr.type is %d and this.type is %d rr.class %d this.class %d", rr.type, this->type, rr.rr_class, this->rr_class); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Resolver: rr.type is %d and this.type is %d rr.class %d this.class %d", rr.type, this->type, rr.rr_class, this->rr_class); if (rr.type != this->type) { curanswer++; @@ -905,7 +934,7 @@ void Resolver::TriggerCachedResult() /** High level abstraction of dns used by application at large */ Resolver::Resolver(const std::string &source, QueryType qt, bool &cached, Module* creator) : Creator(creator), input(source), querytype(qt) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Resolver::Resolver"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Resolver::Resolver"); cached = false; CQ = ServerInstance->Res->GetCache(source); @@ -948,7 +977,7 @@ Resolver::Resolver(const std::string &source, QueryType qt, bool &cached, Module break; default: - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS request with unknown query type %d", querytype); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS request with unknown query type %d", querytype); this->myid = -1; break; } @@ -958,7 +987,7 @@ Resolver::Resolver(const std::string &source, QueryType qt, bool &cached, Module } else { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"DNS request id %d", this->myid); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"DNS request id %d", this->myid); } } @@ -991,11 +1020,11 @@ void DNS::HandleEvent(EventType, int) /* Fetch the id and result of the next available packet */ DNSResult res(0,"",0,""); res.id = 0; - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Handle DNS event"); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Handle DNS event"); res = this->GetResult(); - ServerInstance->Logs->Log("RESOLVER",DEBUG,"Result id %d", res.id); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"Result id %d", res.id); /* Is there a usable request id? */ if (res.id != -1) @@ -1041,7 +1070,7 @@ void DNS::HandleEvent(EventType, int) /** Add a derived Resolver to the working set */ bool DNS::AddResolverClass(Resolver* r) { - ServerInstance->Logs->Log("RESOLVER",DEBUG,"AddResolverClass 0x%08lx", (unsigned long)r); + ServerInstance->Logs->Log("RESOLVER",LOG_DEBUG,"AddResolverClass 0x%08lx", (unsigned long)r); /* Check the pointers validity and the id's validity */ if ((r) && (r->GetId() > -1)) { @@ -1055,20 +1084,13 @@ bool DNS::AddResolverClass(Resolver* r) Classes[r->GetId()] = r; return true; } - else - /* Duplicate id */ - return false; } - else - { - /* Pointer or id not valid. - * Free the item and return - */ - if (r) - delete r; - return false; - } + /* Pointer or id not valid, or duplicate id. + * Free the item and return + */ + delete r; + return false; } void DNS::CleanResolvers(Module* module)