2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2017, 2019, 2021 Sadie Powell <sadie@witchery.services>
5 * Copyright (C) 2014-2015 Attila Molnar <attilamolnar@hush.com>
6 * Copyright (C) 2013, 2015-2016 Adam <Adam@anope.org>
8 * This file is part of InspIRCd. InspIRCd is free software: you can
9 * redistribute it and/or modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation, version 2.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
31 /* A simple A lookup */
35 /* Reverse DNS lookup */
39 /* IPv6 AAAA lookup */
43 /** Flags that can be AND'd into DNSPacket::flags to receive certain values
47 QUERYFLAGS_QR = 0x8000,
48 QUERYFLAGS_OPCODE = 0x7800,
49 QUERYFLAGS_AA = 0x400,
50 QUERYFLAGS_TC = 0x200,
51 QUERYFLAGS_RD = 0x100,
54 QUERYFLAGS_RCODE = 0xF
66 ERROR_NONSTANDARD_QUERY,
69 ERROR_DOMAIN_NOT_FOUND,
70 ERROR_NOT_IMPLEMENTED,
76 typedef uint16_t RequestId;
80 class Exception : public ModuleException
83 Exception(const std::string& message) : ModuleException(message) { }
91 Question() : type(QUERY_NONE) { }
92 Question(const std::string& n, QueryType t) : name(n), type(t) { }
93 bool operator==(const Question& other) const { return ((name == other.name) && (type == other.type)); }
94 bool operator!=(const Question& other) const { return (!(*this == other)); }
98 size_t operator()(const Question& question) const
100 return irc::insensitive()(question.name);
105 struct ResourceRecord : Question
111 ResourceRecord(const std::string& n, QueryType t) : Question(n, t), ttl(0), created(ServerInstance->Time()) { }
112 ResourceRecord(const Question& question) : Question(question), ttl(0), created(ServerInstance->Time()) { }
118 std::vector<ResourceRecord> answers;
122 Query() : error(ERROR_NONE), cached(false) { }
123 Query(const Question& q) : question(q), error(ERROR_NONE), cached(false) { }
125 const ResourceRecord* FindAnswerOfType(QueryType qtype) const
127 for (std::vector<DNS::ResourceRecord>::const_iterator i = answers.begin(); i != answers.end(); ++i)
129 const DNS::ResourceRecord& rr = *i;
130 if (rr.type == qtype)
143 class Manager : public DataProvider
146 Manager(Module* mod) : DataProvider(mod, "DNS") { }
148 virtual void Process(Request* req) = 0;
149 virtual void RemoveRequest(Request* req) = 0;
150 virtual std::string GetErrorStr(Error) = 0;
151 virtual std::string GetTypeStr(QueryType) = 0;
156 class Request : public Timer
159 Manager* const manager;
162 /* Use result cache if available */
166 /* Creator of this request */
167 Module* const creator;
169 Request(Manager* mgr, Module* mod, const std::string& addr, QueryType qt, bool usecache = true, unsigned int timeout = 0)
170 : Timer(timeout ? timeout : ServerInstance->Config->ConfValue("dns")->getDuration("timeout", 5, 1))
173 , use_cache(usecache)
181 manager->RemoveRequest(this);
184 /** Called when this request succeeds
185 * @param req The query sent back from the nameserver
187 virtual void OnLookupComplete(const Query* req) = 0;
189 /** Called when this request fails or times out.
190 * @param req The query sent back from the nameserver, check the error code.
192 virtual void OnError(const Query* req) { }
194 /** Used to time out the query, calls OnError and asks the TimerManager
195 * to delete this request
197 bool Tick(time_t now) CXX11_OVERRIDE
199 Query rr(this->question);
200 rr.error = ERROR_TIMEDOUT;