diff options
-rw-r--r-- | include/dns.h | 61 | ||||
-rw-r--r-- | src/dns.cpp | 135 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_testcommand.cpp | 2 |
4 files changed, 59 insertions, 141 deletions
diff --git a/include/dns.h b/include/dns.h index b9ba27e2e..522b58ee5 100644 --- a/include/dns.h +++ b/include/dns.h @@ -23,11 +23,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "socket.h" #include "base.h" -struct dns_ip4list -{ - insp_inaddr ip; - dns_ip4list *next; -}; +typedef std::pair<int,std::string> DNSResult; /** * Error types that class Resolver can emit to its error method. @@ -41,25 +37,20 @@ enum ResolverError }; -/** The DNS class allows fast nonblocking resolution of hostnames - * and ip addresses. It is based heavily upon firedns by Ian Gulliver. - * Modules SHOULD avoid using this class to resolve hostnames and IP - * addresses, as it is a low-level wrapper around the UDP socket routines - * and is probably not abstracted enough for real use. Please see the - * Resolver class if you wish to resolve hostnames. +/** DNS is a singleton class used by the core to dispatch dns + * requests to the dns server, and route incoming dns replies + * back to Resolver objects, based upon the request ID. You + * should never use this class yourself. */ class DNS : public Extensible { private: - insp_inaddr *binip; - unsigned char* result; - unsigned char localbuf[1024]; int t; int myid; public: int dns_getip4(const char* name); int dns_getname4(const insp_inaddr* ip); - int dns_getresult(); + DNSResult dns_getresult(); DNS(); ~DNS(); }; @@ -76,11 +67,7 @@ class DNS : public Extensible */ class Resolver : public Extensible { - private: - /** - * The lowlevel DNS object used by Resolver - */ - DNS Query; + protected: /** * The input data, either a host or an IP address */ @@ -95,13 +82,11 @@ class Resolver : public Extensible */ std::string server; /** - * The file descriptor used for the DNS lookup + * The ID allocated to your lookup. This is a pseud-random number + * between 0 and 65535, a value of -1 indicating a failure. + * The core uses this to route results to the correct objects. */ int myid; - /** - * The output data, e.g. a hostname or an IP. - */ - std::string result; public: /** * Initiate DNS lookup. Your class should not attempt to delete or free these @@ -114,14 +99,13 @@ class Resolver : public Extensible * @param forward Set to true to perform a forward lookup (hostname to ip) or false * to perform a reverse lookup (ip to hostname). Lookups on A records and PTR * records are supported. CNAME and MX are not supported by this resolver. - * @param dnsserver This optional parameter specifies an alterate nameserver to use. - * If it is not specified, or is an empty string, the value of ServerConfig::DNSServer - * is used instead. + * If InspIRCd is compiled with ipv6 support, lookups on AAAA records are preferred + * and supported over A records. * @throw ModuleException This class may throw an instance of ModuleException, in the - * event there are no more file descriptors, or a similar hard error occurs such as + * event a lookup could not be allocated, or a similar hard error occurs such as * the network being down. */ - Resolver(const std::string &source, bool forward, const std::string &dnsserver); + Resolver(const std::string &source, bool forward); /** * The default destructor does nothing. */ @@ -142,7 +126,7 @@ class Resolver : public Extensible * for reading, and will then dispatch a call to either OnLookupComplete or * OnError. You should never call this method yourself. */ - bool ProcessResult(); + bool ProcessResult(const std::string &result); /** * Returns the file descriptor of this class. This is primarily used by the core * to determine where in various tables to place a pointer to your class, but it @@ -152,11 +136,13 @@ class Resolver : public Extensible }; /** - * Clear the pointer table used for Resolver classes + * Clear the pointer table used for Resolver classes, + * translate ServerConfig::DNSServer into an insp_inaddr, + * establish binding on UDP socket for DNS requests. */ void init_dns(); /** - * Deal with a Resolver class which has become writeable + * Deal with a Resolver class which has become readable */ void dns_deal_with_classes(int fd); /** @@ -164,13 +150,4 @@ void dns_deal_with_classes(int fd); */ bool dns_add_class(Resolver* r); -#ifdef THREADED_DNS -/** This is the handler function for multi-threaded DNS. - * It cannot be a class member as pthread will not let us - * create a thread whos handler function is a member of - * a class (ugh). - */ -void* dns_task(void* arg); -#endif - #endif diff --git a/src/dns.cpp b/src/dns.cpp index a8268aafc..e0cb3ccaa 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -69,16 +69,10 @@ typedef connlist::iterator connlist_iter; DNS* Res = NULL; -/* As lookups are completed, they are pushed into this result_list */ -std::map<int, std::string> result_list; connlist connections; - int master_socket = -1; - Resolver* dns_classes[65536]; - -insp_inaddr servers[8]; -int i4; +insp_inaddr myserver; class s_rr_middle { @@ -109,7 +103,6 @@ class s_connection unsigned char res[512]; unsigned int _class; QueryType type; - int want_list; s_connection() { @@ -185,14 +178,13 @@ int s_connection::send_requests(const s_header *h, const int l) dns_empty_header(payload,h,l); - /* otherwise send via standard ipv4 boringness */ memset(&addr,0,sizeof(addr)); #ifdef IPV6 - memcpy(&addr.sin6_addr,&servers[0],sizeof(addr.sin6_addr)); + 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,&servers[0],sizeof(addr.sin_addr)); + memcpy(&addr.sin_addr.s_addr,&myserver,sizeof(addr.sin_addr)); addr.sin_family = AF_FAMILY; addr.sin_port = htons(53); #endif @@ -211,7 +203,6 @@ s_connection* dns_add_query(s_header *h, int &id) id = rand() % 65536; s_connection * s = new s_connection(); - /* set header flags */ h->id[0] = s->id[0] = id >> 8; h->id[1] = s->id[1] = id & 0xFF; h->flags1 = 0 | FLAGS1_MASK_RD; @@ -220,7 +211,7 @@ s_connection* dns_add_query(s_header *h, int &id) h->ancount = 0; h->nscount = 0; h->arcount = 0; - s->want_list = 0; + if (connections.find(id) == connections.end()) connections[id] = s; return s; @@ -230,11 +221,10 @@ void create_socket() { log(DEBUG,"---- BEGIN DNS INITIALIZATION, SERVER=%s ---",Config->DNSServer); insp_inaddr addr; - i4 = 0; srand((unsigned int) TIME); - memset(servers,'\0',sizeof(insp_inaddr) * 8); + memset(&myserver,0,sizeof(insp_inaddr)); if (insp_aton(Config->DNSServer,&addr) > 0) - memcpy(&servers[i4++],&addr,sizeof(insp_inaddr)); + memcpy(&myserver,&addr,sizeof(insp_inaddr)); master_socket = socket(PF_PROTOCOL, SOCK_DGRAM, 0); if (master_socket != -1) @@ -373,10 +363,9 @@ int DNS::dns_getname4(const insp_inaddr *ip) #endif } -/* Return the next id which is ready. - * result_list[id] will have been populated with the result string. +/* Return the next id which is ready, and the result attached to it */ -int DNS::dns_getresult() +DNSResult DNS::dns_getresult() { /* retrieve result of DNS query (buffered) */ s_header h; @@ -387,7 +376,7 @@ int DNS::dns_getresult() length = recv(master_socket,buffer,sizeof(s_header),0); if (length < 12) - return -1; + return std::make_pair(-1,""); dns_fill_header(&h,buffer,length - 12); @@ -400,7 +389,7 @@ int DNS::dns_getresult() 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 -1; + return std::make_pair(-1,""); } else { @@ -410,10 +399,11 @@ int DNS::dns_getresult() connections.erase(n_iter); } unsigned char* a = c->result_ready(h, length); + std::string resultstr; if (a == NULL) { - result_list[this_id] = ""; + resultstr = ""; } else { @@ -421,16 +411,16 @@ int DNS::dns_getresult() { char formatted[1024]; snprintf(formatted,1024,"%u.%u.%u.%u",a[0],a[1],a[2],a[3]); - result_list[this_id] = std::string(formatted); + resultstr = std::string(formatted); } else { - result_list[this_id] = std::string((const char*)a); + resultstr = std::string((const char*)a); } } delete c; - return this_id; + return std::make_pair(this_id,resultstr); } /** A result is ready, process it @@ -564,54 +554,6 @@ unsigned char* s_connection::result_ready(s_header &h, int length) break; case DNS_QRY_A: log(DEBUG,"DNS: got a result of type DNS_QRY_A"); - if (this->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) - { - return NULL; - } - memcpy(&alist->ip,&h.payload[i],4); - if ((unsigned)++curanswer >= h.ancount) - break; - i += rr.rdlength; - q = 0; - while (q == 0 && i < length) - { - 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 (length - i < 10) - { - 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; @@ -632,7 +574,7 @@ DNS::~DNS() { } -Resolver::Resolver(const std::string &source, bool forward, const std::string &dnsserver = "") : input(source), fwd(forward), server(dnsserver) +Resolver::Resolver(const std::string &source, bool forward) : input(source), fwd(forward) { if (forward) { @@ -651,8 +593,7 @@ Resolver::Resolver(const std::string &source, bool forward, const std::string &d { log(DEBUG,"Resolver::Resolver: Could not get an id!"); this->OnError(RESOLVER_NSDOWN); - ModuleException e("Resolver: Couldnt get an id to make a request"); - throw e; + throw ModuleException("Resolver: Couldnt get an id to make a request"); /* We shouldnt get here really */ return; } @@ -660,6 +601,14 @@ Resolver::Resolver(const std::string &source, bool forward, const std::string &d log(DEBUG,"Resolver::Resolver: this->myid=%d",this->myid); } +void Resolver::OnLookupComplete(const std::string &result) +{ +} + +void Resolver::OnError(ResolverError e) +{ +} + Resolver::~Resolver() { log(DEBUG,"Resolver::~Resolver"); @@ -670,13 +619,11 @@ int Resolver::GetId() return this->myid; } -bool Resolver::ProcessResult() +bool Resolver::ProcessResult(const std::string &result) { log(DEBUG,"Resolver::ProcessResult"); - std::map<int, std::string>::iterator x = result_list.find(this->myid); - - if (x == result_list.end()) + if (!result.length()) { log(DEBUG,"Resolver::OnError(RESOLVER_NXDOMAIN)"); this->OnError(RESOLVER_NXDOMAIN); @@ -685,33 +632,27 @@ bool Resolver::ProcessResult() else { - log(DEBUG,"Resolver::OnLookupComplete(%s)",x->second.c_str()); - this->OnLookupComplete(x->second); - result_list.erase(x); + log(DEBUG,"Resolver::OnLookupComplete(%s)",result.c_str()); + this->OnLookupComplete(result); return true; } } -void Resolver::OnLookupComplete(const std::string &result) -{ -} - -void Resolver::OnError(ResolverError e) -{ -} - void dns_deal_with_classes(int fd) { log(DEBUG,"dns_deal_with_classes(%d)",fd); if (fd == master_socket) { - int id = Res->dns_getresult(); - if (id != -1) + DNSResult res = Res->dns_getresult(); + if (res.first != -1) { - log(DEBUG,"Result available, id=%d",id); - dns_classes[id]->ProcessResult(); - delete dns_classes[id]; - dns_classes[id] = NULL; + 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; + } } } } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 6426e054a..688da6f05 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -56,7 +56,7 @@ class CGIResolver : public Resolver bool notify; public: CGIResolver(bool NotifyOpers, const std::string &source, bool forward, userrec* u, int userfd, const std::string &type) - : Resolver(source, forward, ""), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { } + : Resolver(source, forward), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { } virtual void OnLookupComplete(const std::string &result) { diff --git a/src/modules/m_testcommand.cpp b/src/modules/m_testcommand.cpp index 1f8aaac1a..3b27d01d9 100644 --- a/src/modules/m_testcommand.cpp +++ b/src/modules/m_testcommand.cpp @@ -28,7 +28,7 @@ using namespace std; class MyResolver : public Resolver { public: - MyResolver(const std::string &source, bool forward, const std::string &dnsserver = "") : Resolver(source, forward, dnsserver) { } + MyResolver(const std::string &source, bool forward) : Resolver(source, forward) { } virtual void OnLookupComplete(const std::string &result) { |