2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2013 Adam <Adam@anope.org>
5 * Copyright (C) 2003-2013 Anope Team <team@anope.org>
7 * This file is part of InspIRCd. InspIRCd is free software: you can
8 * redistribute it and/or modify it under the terms of the GNU General Public
9 * License as published by the Free Software Foundation, version 2.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 /* A simple A lookup */
34 /* Reverse DNS lookup */
36 /* IPv6 AAAA lookup */
40 /** Flags that can be AND'd into DNSPacket::flags to receive certain values
44 QUERYFLAGS_QR = 0x8000,
45 QUERYFLAGS_OPCODE = 0x7800,
46 QUERYFLAGS_AA = 0x400,
47 QUERYFLAGS_TC = 0x200,
48 QUERYFLAGS_RD = 0x100,
51 QUERYFLAGS_RCODE = 0xF
61 ERROR_NONSTANDARD_QUERY,
64 ERROR_DOMAIN_NOT_FOUND,
65 ERROR_NOT_IMPLEMENTED,
74 * The maximum value of a dns request id,
75 * 16 bits wide, 0xFFFF.
77 const int MAX_REQUEST_ID = 0xFFFF;
79 class Exception : public ModuleException
82 Exception(const std::string& message) : ModuleException(message) { }
89 unsigned short qclass;
91 Question() : type(QUERY_NONE), qclass(0) { }
92 Question(const std::string& n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
93 inline bool operator==(const Question& other) const { return name == other.name && type == other.type && qclass == other.qclass; }
97 size_t operator()(const Question& question) const
99 return irc::insensitive()(question.name);
104 struct ResourceRecord : Question
110 ResourceRecord(const std::string& n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(ServerInstance->Time()) { }
111 ResourceRecord(const Question& question) : Question(question), ttl(0), created(ServerInstance->Time()) { }
116 std::vector<Question> questions;
117 std::vector<ResourceRecord> answers;
121 Query() : error(ERROR_NONE), cached(false) { }
122 Query(const Question& question) : error(ERROR_NONE), cached(false) { questions.push_back(question); }
130 class Manager : public DataProvider
133 Manager(Module* mod) : DataProvider(mod, "DNS") { }
135 virtual void Process(Request* req) = 0;
136 virtual void RemoveRequest(Request* req) = 0;
137 virtual std::string GetErrorStr(Error) = 0;
142 class Request : public Timer, public Question
145 Manager* const manager;
147 /* Use result cache if available */
151 /* Creator of this request */
152 Module* const creator;
154 Request(Manager* mgr, Module* mod, const std::string& addr, QueryType qt, bool usecache = true)
155 : Timer((ServerInstance->Config->dns_timeout ? ServerInstance->Config->dns_timeout : 5), ServerInstance->Time())
158 , use_cache(usecache)
162 ServerInstance->Timers->AddTimer(this);
167 manager->RemoveRequest(this);
170 /** Called when this request succeeds
171 * @param r The query sent back from the nameserver
173 virtual void OnLookupComplete(const Query* req) = 0;
175 /** Called when this request fails or times out.
176 * @param r The query sent back from the nameserver, check the error code.
178 virtual void OnError(const Query* req) { }
180 /** Used to time out the query, calls OnError and asks the TimerManager
181 * to delete this request
183 bool Tick(time_t now)
186 rr.error = ERROR_TIMEDOUT;