diff options
Diffstat (limited to 'modules/commands/os_dns.cpp')
-rw-r--r-- | modules/commands/os_dns.cpp | 948 |
1 files changed, 0 insertions, 948 deletions
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp deleted file mode 100644 index 7dad85d56..000000000 --- a/modules/commands/os_dns.cpp +++ /dev/null @@ -1,948 +0,0 @@ -/* - * - * (C) 2003-2017 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - */ - -#include "module.h" -#include "modules/dns.h" - -static ServiceReference<DNS::Manager> dnsmanager("DNS::Manager", "dns/manager"); - -struct DNSZone; -class DNSServer; - -static Serialize::Checker<std::vector<DNSZone *> > zones("DNSZone"); -static Serialize::Checker<std::vector<DNSServer *> > dns_servers("DNSServer"); - -static std::map<Anope::string, std::list<time_t> > server_quit_times; - -struct DNSZone : Serializable -{ - Anope::string name; - std::set<Anope::string, ci::less> servers; - - DNSZone(const Anope::string &n) : Serializable("DNSZone"), name(n) - { - zones->push_back(this); - } - - ~DNSZone() - { - std::vector<DNSZone *>::iterator it = std::find(zones->begin(), zones->end(), this); - if (it != zones->end()) - zones->erase(it); - } - - void Serialize(Serialize::Data &data) const anope_override - { - data["name"] << name; - unsigned count = 0; - for (std::set<Anope::string, ci::less>::iterator it = servers.begin(), it_end = servers.end(); it != it_end; ++it) - data["server" + stringify(count++)] << *it; - } - - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data) - { - DNSZone *zone; - Anope::string zone_name; - - data["name"] >> zone_name; - - if (obj) - { - zone = anope_dynamic_static_cast<DNSZone *>(obj); - data["name"] >> zone->name; - } - else - zone = new DNSZone(zone_name); - - zone->servers.clear(); - for (unsigned count = 0; true; ++count) - { - Anope::string server_str; - data["server" + stringify(count)] >> server_str; - if (server_str.empty()) - break; - zone->servers.insert(server_str); - } - - return zone; - } - - static DNSZone *Find(const Anope::string &name) - { - for (unsigned i = 0; i < zones->size(); ++i) - if (zones->at(i)->name.equals_ci(name)) - { - DNSZone *z = zones->at(i); - z->QueueUpdate(); - return z; - } - return NULL; - } -}; - -class DNSServer : public Serializable -{ - Anope::string server_name; - std::vector<Anope::string> ips; - unsigned limit; - /* wants to be in the pool */ - bool pooled; - /* is actually in the pool */ - bool active; - - public: - std::set<Anope::string, ci::less> zones; - time_t repool; - - DNSServer(const Anope::string &sn) : Serializable("DNSServer"), server_name(sn), limit(0), pooled(false), active(false), repool(0) - { - dns_servers->push_back(this); - } - - ~DNSServer() - { - std::vector<DNSServer *>::iterator it = std::find(dns_servers->begin(), dns_servers->end(), this); - if (it != dns_servers->end()) - dns_servers->erase(it); - } - - const Anope::string &GetName() const { return server_name; } - std::vector<Anope::string> &GetIPs() { return ips; } - unsigned GetLimit() const { return limit; } - void SetLimit(unsigned l) { limit = l; } - - bool Pooled() const { return pooled; } - void Pool(bool p) - { - if (!p) - this->SetActive(p); - pooled = p; - } - - bool Active() const { return pooled && active; } - void SetActive(bool p) - { - if (p) - this->Pool(p); - active = p; - - if (dnsmanager) - { - dnsmanager->UpdateSerial(); - for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it) - dnsmanager->Notify(*it); - } - } - - void Serialize(Serialize::Data &data) const anope_override - { - data["server_name"] << server_name; - for (unsigned i = 0; i < ips.size(); ++i) - data["ip" + stringify(i)] << ips[i]; - data["limit"] << limit; - data["pooled"] << pooled; - unsigned count = 0; - for (std::set<Anope::string, ci::less>::iterator it = zones.begin(), it_end = zones.end(); it != it_end; ++it) - data["zone" + stringify(count++)] << *it; - } - - static Serializable* Unserialize(Serializable *obj, Serialize::Data &data) - { - DNSServer *req; - Anope::string server_name; - - data["server_name"] >> server_name; - - if (obj) - { - req = anope_dynamic_static_cast<DNSServer *>(obj); - req->server_name = server_name; - } - else - req = new DNSServer(server_name); - - for (unsigned i = 0; true; ++i) - { - Anope::string ip_str; - data["ip" + stringify(i)] >> ip_str; - if (ip_str.empty()) - break; - req->ips.push_back(ip_str); - } - - data["limit"] >> req->limit; - data["pooled"] >> req->pooled; - - req->zones.clear(); - for (unsigned i = 0; true; ++i) - { - Anope::string zone_str; - data["zone" + stringify(i)] >> zone_str; - if (zone_str.empty()) - break; - req->zones.insert(zone_str); - } - - return req; - } - - static DNSServer *Find(const Anope::string &s) - { - for (unsigned i = 0; i < dns_servers->size(); ++i) - if (dns_servers->at(i)->GetName().equals_ci(s)) - { - DNSServer *serv = dns_servers->at(i); - serv->QueueUpdate(); - return serv; - } - return NULL; - } -}; - -class CommandOSDNS : public Command -{ - void DisplayPoolState(CommandSource &source) - { - if (dns_servers->empty()) - { - source.Reply(_("There are no configured servers.")); - return; - } - - ListFormatter lf(source.GetAccount()); - lf.AddColumn(_("Server")).AddColumn(_("IP")).AddColumn(_("Limit")).AddColumn(_("State")); - for (unsigned i = 0; i < dns_servers->size(); ++i) - { - DNSServer *s = dns_servers->at(i); - Server *srv = Server::Find(s->GetName(), true); - - ListFormatter::ListEntry entry; - entry["Server"] = s->GetName(); - entry["Limit"] = s->GetLimit() ? stringify(s->GetLimit()) : Language::Translate(source.GetAccount(), _("None")); - - Anope::string ip_str; - for (unsigned j = 0; j < s->GetIPs().size(); ++j) - ip_str += s->GetIPs()[j] + " "; - ip_str.trim(); - if (ip_str.empty()) - ip_str = "None"; - entry["IP"] = ip_str; - - if (s->Active()) - entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Active")); - else if (s->Pooled()) - entry["State"] = Language::Translate(source.GetAccount(), _("Pooled/Not Active")); - else - entry["State"] = Language::Translate(source.GetAccount(), _("Unpooled")); - - if (!srv) - entry["State"] += Anope::string(" ") + Language::Translate(source.GetAccount(), _("(Split)")); - - lf.AddEntry(entry); - } - - std::vector<Anope::string> replies; - lf.Process(replies); - - if (!zones->empty()) - { - ListFormatter lf2(source.GetAccount()); - lf2.AddColumn(_("Zone")).AddColumn(_("Servers")); - - for (unsigned i = 0; i < zones->size(); ++i) - { - const DNSZone *z = zones->at(i); - - ListFormatter::ListEntry entry; - entry["Zone"] = z->name; - - Anope::string server_str; - for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it) - server_str += *it + " "; - server_str.trim(); - - if (server_str.empty()) - server_str = "None"; - - entry["Servers"] = server_str; - - lf2.AddEntry(entry); - } - - lf2.Process(replies); - } - - for (unsigned i = 0; i < replies.size(); ++i) - source.Reply(replies[i]); - } - - void AddZone(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - const Anope::string &zone = params[1]; - - if (DNSZone::Find(zone)) - { - source.Reply(_("Zone %s already exists."), zone.c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - Log(LOG_ADMIN, source, this) << "to add zone " << zone; - - new DNSZone(zone); - source.Reply(_("Added zone %s."), zone.c_str()); - } - - void DelZone(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - const Anope::string &zone = params[1]; - - DNSZone *z = DNSZone::Find(zone); - if (!z) - { - source.Reply(_("Zone %s does not exist."), zone.c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - Log(LOG_ADMIN, source, this) << "to delete zone " << z->name; - - for (std::set<Anope::string, ci::less>::iterator it = z->servers.begin(), it_end = z->servers.end(); it != it_end; ++it) - { - DNSServer *s = DNSServer::Find(*it); - if (s) - s->zones.erase(z->name); - } - - if (dnsmanager) - { - dnsmanager->UpdateSerial(); - dnsmanager->Notify(z->name); - } - - source.Reply(_("Zone %s removed."), z->name.c_str()); - delete z; - } - - void AddServer(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - const Anope::string &zone = params.size() > 2 ? params[2] : ""; - - if (s) - { - if (zone.empty()) - { - source.Reply(_("Server %s already exists."), s->GetName().c_str()); - } - else - { - DNSZone *z = DNSZone::Find(zone); - if (!z) - { - source.Reply(_("Zone %s does not exist."), zone.c_str()); - return; - } - else if (z->servers.count(s->GetName())) - { - source.Reply(_("Server %s is already in zone %s."), s->GetName().c_str(), z->name.c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - z->servers.insert(s->GetName()); - s->zones.insert(zone); - - if (dnsmanager) - { - dnsmanager->UpdateSerial(); - dnsmanager->Notify(zone); - } - - Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << z->name; - - source.Reply(_("Server %s added to zone %s."), s->GetName().c_str(), z->name.c_str()); - } - - return; - } - - Server *serv = Server::Find(params[1], true); - if (!serv || serv == Me || serv->IsJuped()) - { - source.Reply(_("Server %s is not linked to the network."), params[1].c_str()); - return; - } - - s = new DNSServer(params[1]); - if (zone.empty()) - { - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - Log(LOG_ADMIN, source, this) << "to add server " << s->GetName(); - source.Reply(_("Added server %s."), s->GetName().c_str()); - } - else - { - DNSZone *z = DNSZone::Find(zone); - if (!z) - { - source.Reply(_("Zone %s does not exist."), zone.c_str()); - delete s; - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - Log(LOG_ADMIN, source, this) << "to add server " << s->GetName() << " to zone " << zone; - - z->servers.insert(s->GetName()); - s->zones.insert(z->name); - - if (dnsmanager) - { - dnsmanager->UpdateSerial(); - dnsmanager->Notify(z->name); - } - } - } - - void DelServer(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - const Anope::string &zone = params.size() > 2 ? params[2] : ""; - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - else if (!zone.empty()) - { - DNSZone *z = DNSZone::Find(zone); - if (!z) - { - source.Reply(_("Zone %s does not exist."), zone.c_str()); - return; - } - else if (!z->servers.count(s->GetName())) - { - source.Reply(_("Server %s is not in zone %s."), s->GetName().c_str(), z->name.c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - Log(LOG_ADMIN, source, this) << "to remove server " << s->GetName() << " from zone " << z->name; - - if (dnsmanager) - { - dnsmanager->UpdateSerial(); - dnsmanager->Notify(z->name); - } - - z->servers.erase(s->GetName()); - s->zones.erase(z->name); - source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str()); - return; - } - else if (Server::Find(s->GetName(), true)) - { - source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str()); - return; - } - - for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it) - { - DNSZone *z = DNSZone::Find(*it); - if (z) - z->servers.erase(s->GetName()); - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - if (dnsmanager) - dnsmanager->UpdateSerial(); - - Log(LOG_ADMIN, source, this) << "to delete server " << s->GetName(); - source.Reply(_("Removed server %s."), s->GetName().c_str()); - delete s; - } - - void AddIP(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - - for (unsigned i = 0; i < s->GetIPs().size(); ++i) - if (params[2].equals_ci(s->GetIPs()[i])) - { - source.Reply(_("IP %s already exists for %s."), s->GetIPs()[i].c_str(), s->GetName().c_str()); - return; - } - - sockaddrs addr(params[2]); - if (!addr.valid()) - { - source.Reply(_("%s is not a valid IP address."), params[2].c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - s->GetIPs().push_back(params[2]); - source.Reply(_("Added IP %s to %s."), params[2].c_str(), s->GetName().c_str()); - Log(LOG_ADMIN, source, this) << "to add IP " << params[2] << " to " << s->GetName(); - - if (s->Active() && dnsmanager) - { - dnsmanager->UpdateSerial(); - for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it) - dnsmanager->Notify(*it); - } - } - - void DelIP(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - for (unsigned i = 0; i < s->GetIPs().size(); ++i) - if (params[2].equals_ci(s->GetIPs()[i])) - { - s->GetIPs().erase(s->GetIPs().begin() + i); - source.Reply(_("Removed IP %s from %s."), params[2].c_str(), s->GetName().c_str()); - Log(LOG_ADMIN, source, this) << "to remove IP " << params[2] << " from " << s->GetName(); - - if (s->GetIPs().empty()) - { - s->repool = 0; - s->Pool(false); - } - - if (s->Active() && dnsmanager) - { - dnsmanager->UpdateSerial(); - for (std::set<Anope::string, ci::less>::iterator it = s->zones.begin(), it_end = s->zones.end(); it != it_end; ++it) - dnsmanager->Notify(*it); - } - - return; - } - - source.Reply(_("IP %s does not exist for %s."), params[2].c_str(), s->GetName().c_str()); - } - - void OnSet(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - if (params[2].equals_ci("LIMIT")) - { - try - { - unsigned l = convertTo<unsigned>(params[3]); - s->SetLimit(l); - if (l) - source.Reply(_("User limit for %s set to %d."), s->GetName().c_str(), l); - else - source.Reply(_("User limit for %s removed."), s->GetName().c_str()); - } - catch (const ConvertException &ex) - { - source.Reply(_("Invalid value for LIMIT. Must be numerical.")); - } - } - else - source.Reply(_("Unknown SET option.")); - } - - void OnPool(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - else if (!Server::Find(s->GetName(), true)) - { - source.Reply(_("Server %s is not currently linked."), s->GetName().c_str()); - return; - } - else if (s->Pooled()) - { - source.Reply(_("Server %s is already pooled."), s->GetName().c_str()); - return; - } - else if (s->GetIPs().empty()) - { - source.Reply(_("Server %s has no configured IPs."), s->GetName().c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - s->SetActive(true); - - source.Reply(_("Pooled %s."), s->GetName().c_str()); - Log(LOG_ADMIN, source, this) << "to pool " << s->GetName(); - } - - - void OnDepool(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - DNSServer *s = DNSServer::Find(params[1]); - - if (!s) - { - source.Reply(_("Server %s does not exist."), params[1].c_str()); - return; - } - else if (!s->Pooled()) - { - source.Reply(_("Server %s is not pooled."), s->GetName().c_str()); - return; - } - - if (Anope::ReadOnly) - source.Reply(READ_ONLY_MODE); - - s->Pool(false); - - source.Reply(_("Depooled %s."), s->GetName().c_str()); - Log(LOG_ADMIN, source, this) << "to depool " << s->GetName(); - } - - public: - CommandOSDNS(Module *creator) : Command(creator, "operserv/dns", 0, 4) - { - this->SetDesc(_("Manage DNS zones for this network")); - this->SetSyntax(_("ADDZONE \037zone.name\037")); - this->SetSyntax(_("DELZONE \037zone.name\037")); - this->SetSyntax(_("ADDSERVER \037server.name\037 [\037zone.name\037]")); - this->SetSyntax(_("DELSERVER \037server.name\037 [\037zone.name\037]")); - this->SetSyntax(_("ADDIP \037server.name\037 \037ip\037")); - this->SetSyntax(_("DELIP \037server.name\037 \037ip\037")); - this->SetSyntax(_("SET \037server.name\037 \037option\037 \037value\037")); - this->SetSyntax(_("POOL \037server.name\037")); - this->SetSyntax(_("DEPOOL \037server.name\037")); - } - - void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - if (params.empty()) - this->DisplayPoolState(source); - else if (params[0].equals_ci("ADDZONE") && params.size() > 1) - this->AddZone(source, params); - else if (params[0].equals_ci("DELZONE") && params.size() > 1) - this->DelZone(source, params); - else if (params[0].equals_ci("ADDSERVER") && params.size() > 1) - this->AddServer(source, params); - else if (params[0].equals_ci("DELSERVER") && params.size() > 1) - this->DelServer(source, params); - else if (params[0].equals_ci("ADDIP") && params.size() > 2) - this->AddIP(source, params); - else if (params[0].equals_ci("DELIP") && params.size() > 2) - this->DelIP(source, params); - else if (params[0].equals_ci("SET") && params.size() > 3) - this->OnSet(source, params); - else if (params[0].equals_ci("POOL") && params.size() > 1) - this->OnPool(source, params); - else if (params[0].equals_ci("DEPOOL") && params.size() > 1) - this->OnDepool(source, params); - else - this->OnSyntaxError(source, ""); - } - - bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override - { - this->SendSyntax(source); - source.Reply(" "); - source.Reply(_("This command allows managing DNS zones used for controlling what servers users\n" - "are directed to when connecting. Omitting all parameters prints out the status of\n" - "the DNS zone.\n" - " \n" - "\002ADDZONE\002 adds a zone, eg us.yournetwork.tld. Servers can then be added to this\n" - "zone with the \002ADDSERVER\002 command.\n" - " \n" - "The \002ADDSERVER\002 command adds a server to the given zone. When a query is done, the\n" - "zone in question is served if it exists, else all servers in all zones are served.\n" - "A server may be in more than one zone.\n" - " \n" - "The \002ADDIP\002 command associates an IP with a server.\n" - " \n" - "The \002POOL\002 and \002DEPOOL\002 commands actually add and remove servers to their given zones.")); - return true; - } -}; - -class ModuleDNS : public Module -{ - Serialize::Type zone_type, dns_type; - CommandOSDNS commandosdns; - - time_t ttl; - int user_drop_mark; - time_t user_drop_time; - time_t user_drop_readd_time; - bool remove_split_servers; - bool readd_connected_servers; - - time_t last_warn; - - public: - ModuleDNS(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - zone_type("DNSZone", DNSZone::Unserialize), dns_type("DNSServer", DNSServer::Unserialize), commandosdns(this), - last_warn(0) - { - - - for (unsigned j = 0; j < dns_servers->size(); ++j) - { - DNSServer *s = dns_servers->at(j); - if (s->Pooled() && Server::Find(s->GetName(), true)) - s->SetActive(true); - } - } - - ~ModuleDNS() - { - for (unsigned i = zones->size(); i > 0; --i) - delete zones->at(i - 1); - for (unsigned i = dns_servers->size(); i > 0; --i) - delete dns_servers->at(i - 1); - } - - void OnReload(Configuration::Conf *conf) anope_override - { - Configuration::Block *block = conf->GetModule(this); - this->ttl = block->Get<time_t>("ttl"); - this->user_drop_mark = block->Get<int>("user_drop_mark"); - this->user_drop_time = block->Get<time_t>("user_drop_time"); - this->user_drop_readd_time = block->Get<time_t>("user_drop_readd_time"); - this->remove_split_servers = block->Get<bool>("remove_split_servers"); - this->readd_connected_servers = block->Get<bool>("readd_connected_servers"); - } - - void OnNewServer(Server *s) anope_override - { - if (s == Me || s->IsJuped()) - return; - if (!Me->IsSynced() || this->readd_connected_servers) - { - DNSServer *dns = DNSServer::Find(s->GetName()); - if (dns && dns->Pooled() && !dns->Active() && !dns->GetIPs().empty()) - { - dns->SetActive(true); - Log(this) << "Pooling server " << s->GetName(); - } - } - } - - void OnServerQuit(Server *s) anope_override - { - DNSServer *dns = DNSServer::Find(s->GetName()); - if (remove_split_servers && dns && dns->Pooled() && dns->Active()) - { - if (readd_connected_servers) - dns->SetActive(false); // Will be reactivated when it comes back - else - dns->Pool(false); // Otherwise permanently pull this - Log(this) << "Depooling delinked server " << s->GetName(); - } - } - - void OnUserConnect(User *u, bool &exempt) anope_override - { - if (!u->Quitting() && u->server) - { - DNSServer *s = DNSServer::Find(u->server->GetName()); - /* Check for user limit reached */ - if (s && s->Pooled() && s->Active() && s->GetLimit() && u->server->users >= s->GetLimit()) - { - Log(this) << "Depooling full server " << s->GetName() << ": " << u->server->users << " users"; - s->SetActive(false); - } - } - } - - void OnPreUserLogoff(User *u) anope_override - { - if (u && u->server) - { - DNSServer *s = DNSServer::Find(u->server->GetName()); - if (!s || !s->Pooled()) - return; - - /* Check for dropping under userlimit */ - if (s->GetLimit() && !s->Active() && s->GetLimit() > u->server->users) - { - Log(this) << "Pooling server " << s->GetName(); - s->SetActive(true); - } - - if (this->user_drop_mark > 0) - { - std::list<time_t>& times = server_quit_times[u->server->GetName()]; - times.push_back(Anope::CurTime); - if (times.size() > static_cast<unsigned>(this->user_drop_mark)) - times.pop_front(); - - if (times.size() == static_cast<unsigned>(this->user_drop_mark)) - { - time_t diff = Anope::CurTime - *times.begin(); - - /* Check for very fast user drops */ - if (s->Active() && diff <= this->user_drop_time) - { - Log(this) << "Depooling server " << s->GetName() << ": dropped " << this->user_drop_mark << " users in " << diff << " seconds"; - s->repool = Anope::CurTime + this->user_drop_readd_time; - s->SetActive(false); - } - /* Check for needing to re-pool a server that dropped users */ - else if (!s->Active() && s->repool && s->repool <= Anope::CurTime) - { - s->SetActive(true); - s->repool = 0; - Log(this) << "Pooling server " << s->GetName(); - } - } - } - } - } - - void OnDnsRequest(DNS::Query &req, DNS::Query *packet) anope_override - { - if (req.questions.empty()) - return; - /* Currently we reply to any QR for A/AAAA */ - const DNS::Question& q = req.questions[0]; - if (q.type != DNS::QUERY_A && q.type != DNS::QUERY_AAAA && q.type != DNS::QUERY_AXFR && q.type != DNS::QUERY_ANY) - return; - - DNSZone *zone = DNSZone::Find(q.name); - size_t answer_size = packet->answers.size(); - if (zone) - { - for (std::set<Anope::string, ci::less>::iterator it = zone->servers.begin(), it_end = zone->servers.end(); it != it_end; ++it) - { - DNSServer *s = DNSServer::Find(*it); - if (!s || !s->Active()) - continue; - - for (unsigned j = 0; j < s->GetIPs().size(); ++j) - { - DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; - - if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type) - { - DNS::ResourceRecord rr(q.name, q_type); - rr.ttl = this->ttl; - rr.rdata = s->GetIPs()[j]; - packet->answers.push_back(rr); - } - } - } - } - - if (packet->answers.size() == answer_size) - { - /* Default zone */ - for (unsigned i = 0; i < dns_servers->size(); ++i) - { - DNSServer *s = dns_servers->at(i); - if (!s->Active()) - continue; - - for (unsigned j = 0; j < s->GetIPs().size(); ++j) - { - DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; - - if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type) - { - DNS::ResourceRecord rr(q.name, q_type); - rr.ttl = this->ttl; - rr.rdata = s->GetIPs()[j]; - packet->answers.push_back(rr); - } - } - } - } - - if (packet->answers.size() == answer_size) - { - if (last_warn + 60 < Anope::CurTime) - { - last_warn = Anope::CurTime; - Log(this) << "Warning! There are no pooled servers!"; - } - - /* Something messed up, just return them all and hope one is available */ - for (unsigned i = 0; i < dns_servers->size(); ++i) - { - DNSServer *s = dns_servers->at(i); - - for (unsigned j = 0; j < s->GetIPs().size(); ++j) - { - DNS::QueryType q_type = s->GetIPs()[j].find(':') != Anope::string::npos ? DNS::QUERY_AAAA : DNS::QUERY_A; - - if (q.type == DNS::QUERY_AXFR || q.type == DNS::QUERY_ANY || q_type == q.type) - { - DNS::ResourceRecord rr(q.name, q_type); - rr.ttl = this->ttl; - rr.rdata = s->GetIPs()[j]; - packet->answers.push_back(rr); - } - } - } - - if (packet->answers.size() == answer_size) - { - Log(this) << "Error! There are no servers with any IPs of type " << q.type; - } - } - } -}; - -MODULE_INIT(ModuleDNS) |