]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/coremods/core_hostname_lookup.cpp
Check for errors after calling IOHookProvider::OnAccept()
[user/henk/code/inspircd.git] / src / coremods / core_hostname_lookup.cpp
index c26d3b3d32fc82e5e5f0d3f756f5436eb3d98642..cbd80931c727ab2fd9c00529b2068104660a6e50 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * InspIRCd -- Internet Relay Chat Daemon
  *
- *   Copyright (C) 2013 Adam <Adam@anope.org>
+ *   Copyright (C) 2013-2016 Adam <Adam@anope.org>
  *
  * 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
@@ -37,6 +37,21 @@ class UserResolver : public DNS::Request
         */
        const bool fwd;
 
+       const DNS::ResourceRecord* FindAnswerOfType(const DNS::Query* response, DNS::QueryType qtype)
+       {
+               for (std::vector<DNS::ResourceRecord>::const_iterator it = response->answers.begin(); it != response->answers.end(); ++it)
+               {
+                       const DNS::ResourceRecord& rr = *it;
+
+                       if (rr.type == qtype)
+                       {
+                               return &rr;
+                       }
+               }
+
+               return NULL;
+       }
+
  public:
        /** Create a resolver.
         * @param mgr DNS Manager
@@ -61,29 +76,34 @@ class UserResolver : public DNS::Request
                LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
                if (!bound_user)
                {
-                       ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str());
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str());
                        return;
                }
 
-               const DNS::ResourceRecord& ans_record = r->answers[0];
+               const DNS::ResourceRecord* ans_record = FindAnswerOfType(r, this->type);
+               if (ans_record == NULL)
+               {
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "DNS result for %s: no record of type %d", uuid.c_str(), this->type);
+                       return;
+               }
 
-               ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "DNS result for %s: '%s' -> '%s'", uuid.c_str(), ans_record.name.c_str(), ans_record.rdata.c_str());
+               ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "DNS result for %s: '%s' -> '%s'", uuid.c_str(), ans_record->name.c_str(), ans_record->rdata.c_str());
 
                if (!fwd)
                {
                        // first half of resolution is done. We now need to verify that the host matches.
-                       ph->set(bound_user, ans_record.rdata);
+                       ph->set(bound_user, ans_record->rdata);
 
                        UserResolver* res_forward;
                        if (bound_user->client_sa.sa.sa_family == AF_INET6)
                        {
                                /* IPV6 forward lookup */
-                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_AAAA);
+                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record->rdata, DNS::QUERY_AAAA);
                        }
                        else
                        {
                                /* IPV4 lookup */
-                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_A);
+                               res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record->rdata, DNS::QUERY_A);
                        }
                        try
                        {
@@ -107,7 +127,7 @@ class UserResolver : public DNS::Request
                        if (user_ip->sa.sa_family == AF_INET6)
                        {
                                struct in6_addr res_bin;
-                               if (inet_pton(AF_INET6, ans_record.rdata.c_str(), &res_bin))
+                               if (inet_pton(AF_INET6, ans_record->rdata.c_str(), &res_bin))
                                {
                                        rev_match = !memcmp(&user_ip->in6.sin6_addr, &res_bin, sizeof(res_bin));
                                }
@@ -115,7 +135,7 @@ class UserResolver : public DNS::Request
                        else
                        {
                                struct in_addr res_bin;
-                               if (inet_pton(AF_INET, ans_record.rdata.c_str(), &res_bin))
+                               if (inet_pton(AF_INET, ans_record->rdata.c_str(), &res_bin))
                                {
                                        rev_match = !memcmp(&user_ip->in4.sin_addr, &res_bin, sizeof(res_bin));
                                }
@@ -129,18 +149,18 @@ class UserResolver : public DNS::Request
 
                                if (hostname == NULL)
                                {
-                                       ServerInstance->Logs->Log("RESOLVER", LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup");
+                                       ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup");
                                        bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead.");
                                        return;
                                }
-                               else if (hostname->length() < 65)
+                               else if (hostname->length() <= ServerInstance->Config->Limits.MaxHost)
                                {
                                        /* Hostnames starting with : are not a good thing (tm) */
                                        if ((*hostname)[0] == ':')
                                                hostname->insert(0, "0");
 
                                        bound_user->WriteNotice("*** Found your hostname (" + *hostname + (r->cached ? ") -- cached" : ")"));
-                                       bound_user->host.assign(*hostname, 0, 64);
+                                       bound_user->host.assign(*hostname, 0, ServerInstance->Config->Limits.MaxHost);
                                        bound_user->dhost = bound_user->host;
 
                                        /* Invalidate cache */
@@ -148,7 +168,7 @@ class UserResolver : public DNS::Request
                                }
                                else
                                {
-                                       bound_user->WriteNotice("*** Your hostname is longer than the maximum of 64 characters, using your IP address (" + bound_user->GetIPString() + ") instead.");
+                                       bound_user->WriteNotice("*** Your hostname is longer than the maximum of " + ConvToStr(ServerInstance->Config->Limits.MaxHost) + " characters, using your IP address (" + bound_user->GetIPString() + ") instead.");
                                }
 
                                ph->unset(bound_user);
@@ -170,7 +190,6 @@ class UserResolver : public DNS::Request
                {
                        bound_user->WriteNotice("*** Could not resolve your hostname: " + this->manager->GetErrorStr(query->error) + "; using your IP address (" + bound_user->GetIPString() + ") instead.");
                        dl->set(bound_user, 0);
-                       ServerInstance->stats->statsDnsBad++;
                }
        }
 };
@@ -183,8 +202,8 @@ class ModuleHostnameLookup : public Module
 
  public:
        ModuleHostnameLookup()
-               : dnsLookup("dnsLookup", this)
-               , ptrHosts("ptrHosts", this)
+               : dnsLookup("dnsLookup", ExtensionItem::EXT_USER, this)
+               , ptrHosts("ptrHosts", ExtensionItem::EXT_USER, this)
                , DNS(this, "DNS")
        {
                dl = &dnsLookup;
@@ -215,7 +234,6 @@ class ModuleHostnameLookup : public Module
                        this->dnsLookup.set(user, 0);
                        delete res_reverse;
                        ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
-                       ServerInstance->stats->statsDnsBad++;
                }
        }