/*
* InspIRCd -- Internet Relay Chat Daemon
*
- * Copyright (C) 2013 Adam <Adam@anope.org>
- * Copyright (C) 2003-2013 Anope Team <team@anope.org>
+ * Copyright (C) 2017, 2019 Sadie Powell <sadie@witchery.services>
+ * Copyright (C) 2014-2015 Attila Molnar <attilamolnar@hush.com>
+ * Copyright (C) 2013, 2015-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
QUERY_CNAME = 5,
/* Reverse DNS lookup */
QUERY_PTR = 12,
+ /* TXT */
+ QUERY_TXT = 16,
/* IPv6 AAAA lookup */
QUERY_AAAA = 28
};
enum Error
{
ERROR_NONE,
+ ERROR_DISABLED,
ERROR_UNKNOWN,
ERROR_UNLOADED,
ERROR_TIMEDOUT,
+ ERROR_MALFORMED,
ERROR_NOT_AN_ANSWER,
ERROR_NONSTANDARD_QUERY,
ERROR_FORMAT_ERROR,
ERROR_INVALIDTYPE
};
- const int PORT = 53;
+ typedef uint16_t RequestId;
- /**
- * The maximum value of a dns request id,
- * 16 bits wide, 0xFFFF.
- */
- const int MAX_REQUEST_ID = 0xFFFF;
+ const int PORT = 53;
class Exception : public ModuleException
{
{
std::string name;
QueryType type;
- unsigned short qclass;
- Question() : type(QUERY_NONE), qclass(0) { }
- Question(const std::string& n, QueryType t, unsigned short c = 1) : name(n), type(t), qclass(c) { }
- inline bool operator==(const Question& other) const { return name == other.name && type == other.type && qclass == other.qclass; }
+ Question() : type(QUERY_NONE) { }
+ Question(const std::string& n, QueryType t) : name(n), type(t) { }
+ bool operator==(const Question& other) const { return ((name == other.name) && (type == other.type)); }
+ bool operator!=(const Question& other) const { return (!(*this == other)); }
struct hash
{
std::string rdata;
time_t created;
- ResourceRecord(const std::string& n, QueryType t, unsigned short c = 1) : Question(n, t, c), ttl(0), created(ServerInstance->Time()) { }
+ ResourceRecord(const std::string& n, QueryType t) : Question(n, t), ttl(0), created(ServerInstance->Time()) { }
ResourceRecord(const Question& question) : Question(question), ttl(0), created(ServerInstance->Time()) { }
};
struct Query
{
- std::vector<Question> questions;
+ Question question;
std::vector<ResourceRecord> answers;
Error error;
bool cached;
Query() : error(ERROR_NONE), cached(false) { }
- Query(const Question& question) : error(ERROR_NONE), cached(false) { questions.push_back(question); }
+ Query(const Question& q) : question(q), error(ERROR_NONE), cached(false) { }
+
+ const ResourceRecord* FindAnswerOfType(QueryType qtype) const
+ {
+ for (std::vector<DNS::ResourceRecord>::const_iterator i = answers.begin(); i != answers.end(); ++i)
+ {
+ const DNS::ResourceRecord& rr = *i;
+ if (rr.type == qtype)
+ return &rr;
+ }
+
+ return NULL;
+ }
};
class ReplySocket;
virtual void Process(Request* req) = 0;
virtual void RemoveRequest(Request* req) = 0;
virtual std::string GetErrorStr(Error) = 0;
+ virtual std::string GetTypeStr(QueryType) = 0;
};
/** A DNS query.
*/
- class Request : public Timer, public Question
+ class Request : public Timer
{
protected:
Manager* const manager;
public:
+ Question question;
/* Use result cache if available */
bool use_cache;
/* Request id */
- unsigned short id;
+ RequestId id;
/* Creator of this request */
Module* const creator;
Request(Manager* mgr, Module* mod, const std::string& addr, QueryType qt, bool usecache = true)
- : Timer((ServerInstance->Config->dns_timeout ? ServerInstance->Config->dns_timeout : 5), ServerInstance->Time())
- , Question(addr, qt)
+ : Timer(ServerInstance->Config->ConfValue("dns")->getDuration("timeout", 5, 1))
, manager(mgr)
+ , question(addr, qt)
, use_cache(usecache)
, id(0)
, creator(mod)
{
- ServerInstance->Timers.AddTimer(this);
}
virtual ~Request()
/** Used to time out the query, calls OnError and asks the TimerManager
* to delete this request
*/
- bool Tick(time_t now)
+ bool Tick(time_t now) CXX11_OVERRIDE
{
- Query rr(*this);
+ Query rr(this->question);
rr.error = ERROR_TIMEDOUT;
this->OnError(&rr);
delete this;