/*
* 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
*/
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
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
{
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));
}
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));
}
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 */
}
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);
{
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++;
}
}
};
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;
this->dnsLookup.set(user, 0);
delete res_reverse;
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason());
- ServerInstance->stats->statsDnsBad++;
}
}