From d33a0f75a5c0c584fbb7cc0076da36d494f39494 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 22 Nov 2012 00:50:33 -0500 Subject: Pretty large coding style cleanup, in source doc cleanup, and allow protocol mods to depend on each other --- include/access.h | 78 ++++++-- include/account.h | 178 +++++++++++------- include/anope.h | 224 +++++++++++++++++++---- include/base.h | 38 ++-- include/bots.h | 44 +++-- include/botserv.h | 79 -------- include/channels.h | 147 +++++++++------ include/commands.h | 24 +-- include/config.h | 28 +-- include/defs.h | 8 +- include/dns.h | 481 +++++++++++++++++++++++++------------------------ include/extensible.h | 22 ++- include/extern.h | 108 ----------- include/hashcomp.h | 30 +-- include/language.h | 58 +++++- include/lists.h | 11 +- include/logger.h | 52 ++++-- include/mail.h | 57 +++--- include/memo.h | 19 +- include/messages.h | 277 +++++++++++++++------------- include/modes.h | 216 +++++++++++----------- include/module.h | 8 +- include/modules.h | 74 ++++---- include/oper.h | 177 ------------------ include/opertype.h | 10 +- include/protocol.h | 144 +++++++++++---- include/regchannel.h | 180 ++++++++++++------ include/serialize.h | 172 ++++++++++++------ include/servers.h | 52 ++++-- include/service.h | 84 +++++++-- include/services.h | 10 - include/signals.h | 1 - include/socketengine.h | 3 +- include/sockets.h | 61 +++---- include/threadengine.h | 14 +- include/timers.h | 14 +- include/uplink.h | 11 +- include/users.h | 141 +++++++++------ include/xline.h | 180 ++++++++++++++++++ 39 files changed, 2034 insertions(+), 1481 deletions(-) delete mode 100644 include/botserv.h delete mode 100644 include/extern.h delete mode 100644 include/oper.h create mode 100644 include/xline.h (limited to 'include') diff --git a/include/access.h b/include/access.h index 558dbeb5c..918dd7be6 100644 --- a/include/access.h +++ b/include/access.h @@ -8,7 +8,6 @@ * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. * - * */ #ifndef ACCESS_H @@ -25,19 +24,25 @@ enum ACCESS_FOUNDER = 10001 }; +/* A privilege, probably configured using a privilege{} block. Most + * commands require specific privileges to be executed. The AccessProvider + * backing each ChanAccess determines whether that ChanAccess has a given + * privilege. + */ struct CoreExport Privilege { Anope::string name; Anope::string desc; + /* Rank relative to other privileges */ int rank; - Privilege(const Anope::string &n, const Anope::string &d, int r); + Privilege(const Anope::string &name, const Anope::string &desc, int rank); bool operator==(const Privilege &other) const; }; class CoreExport PrivilegeManager { - static std::vector privs; + static std::vector Privileges; public: static void AddPrivilege(Privilege p); static void RemovePrivilege(Privilege &p); @@ -46,25 +51,34 @@ class CoreExport PrivilegeManager static void ClearPrivileges(); }; - +/* A provider of access. Only used for creating ChanAccesses, as + * they contain pure virtual functions. + */ class CoreExport AccessProvider : public Service { public: - AccessProvider(Module *o, const Anope::string &n); + AccessProvider(Module *owner, const Anope::string &name); virtual ~AccessProvider(); + + /** Creates a new ChanAccess entry using this provider. + * @return The new entry + */ virtual ChanAccess *Create() = 0; private: - static std::list providers; + static std::list Providers; public: static const std::list& GetProviders(); }; +/* Represents one entry of an access list on a channel. */ class CoreExport ChanAccess : public Serializable { public: + /* The provider that created this access entry */ AccessProvider *provider; - serialize_obj ci; + /* Channel this access entry is on */ + Serialize::Reference ci; Anope::string mask; Anope::string creator; time_t last_seen; @@ -73,29 +87,69 @@ class CoreExport ChanAccess : public Serializable ChanAccess(AccessProvider *p); virtual ~ChanAccess(); - Serialize::Data serialize() const anope_override; - static Serializable* unserialize(Serializable *obj, Serialize::Data &); + Serialize::Data Serialize() const anope_override; + static Serializable* Unserialize(Serializable *obj, Serialize::Data &); + /** Check if this access entry matches the given user or account + * @param u The user + * @param nc The account + */ virtual bool Matches(const User *u, const NickCore *nc) const; + + /** Check if this access entry has the given privilege. + * @param name The privilege name + */ virtual bool HasPriv(const Anope::string &name) const = 0; - virtual Anope::string Serialize() const = 0; - virtual void Unserialize(const Anope::string &data) = 0; + /** Serialize the access given by this access entry into a human + * readable form. chanserv/access will return a number, chanserv/xop + * will be AOP, SOP, etc. + */ + virtual Anope::string AccessSerialize() const = 0; + + /** Unserialize this access entry from the given data. This data + * will be fetched from AccessSerialize. + */ + virtual void AccessUnserialize(const Anope::string &data) = 0; + + /* Comparison operators to other Access entries */ bool operator>(const ChanAccess &other) const; bool operator<(const ChanAccess &other) const; bool operator>=(const ChanAccess &other) const; bool operator<=(const ChanAccess &other) const; }; +/* A group of access entries. This is used commonly, for example with ChannelInfo::AccessFor, + * to show what access a user has on a channel because users can match multiple access entries. + */ class CoreExport AccessGroup : public std::vector { public: + /* Channel these access entries are on */ const ChannelInfo *ci; + /* Account these entries affect, if any */ const NickCore *nc; - bool SuperAdmin, Founder; + /* super_admin always gets all privs. founder is a special case where ci->founder == nc */ + bool super_admin, founder; + AccessGroup(); + + /** Check if this access group has a certain privilege. Eg, it + * will check every ChanAccess entry of this group for any that + * has the given privilege. + * @param priv The privilege + * @return true if any entry has the given privilege + */ bool HasPriv(const Anope::string &priv) const; + + /** Get the "highest" access entry from this group of entries. + * The highest entry is determined by the entry that has the privilege + * with the highest rank (see Privilege::rank). + * @return The "highest" entry + */ const ChanAccess *Highest() const; + + /* Comparison operators to other AccessGroups */ bool operator>(const AccessGroup &other) const; bool operator<(const AccessGroup &other) const; bool operator>=(const AccessGroup &other) const; diff --git a/include/account.h b/include/account.h index 8ed1f06a4..a45bf8c90 100644 --- a/include/account.h +++ b/include/account.h @@ -7,8 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. - * - * + * */ #ifndef ACCOUNT_H @@ -23,10 +22,8 @@ typedef Anope::hash_map nickalias_map; typedef Anope::hash_map nickcore_map; -extern CoreExport serialize_checker NickAliasList; -extern CoreExport serialize_checker NickCoreList; - -/* NickServ nickname structures. */ +extern CoreExport Serialize::Checker NickAliasList; +extern CoreExport Serialize::Checker NickCoreList; /** Flags set on NickAliases */ @@ -50,10 +47,6 @@ enum NickNameFlag NS_END }; -const Anope::string NickNameFlagStrings[] = { - "BEGIN", "NO_EXPIRE", "HELD", "COLLIDED", "" -}; - /** Flags set on NickCores */ enum NickCoreFlag @@ -101,40 +94,36 @@ enum NickCoreFlag NI_END }; -const Anope::string NickCoreFlagStrings[] = { - "BEGIN", "KILLPROTECT", "SECURE", "MSG", "MEMO_HARDMAX", "MEMO_SIGNON", "MEMO_RECEIVE", - "PRIVATE", "HIDE_EMAIL", "HIDE_MASK", "HIDE_QUIT", "KILL_QUICK", "KILL_IMMED", - "MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "UNCONFIRMED", "STATS", "" -}; - -/* It matters that Base is here before Extensible (it is inherited by Serializable) */ -class CoreExport NickAlias : public Serializable, public Extensible, public Flags +/* A registered nickname. + * It matters that Base is here before Extensible (it is inherited by Serializable) + */ +class CoreExport NickAlias : public Serializable, public Extensible, public Flags { Anope::string vhost_ident, vhost_host, vhost_creator; time_t vhost_created; public: - /** Default constructor + Anope::string nick; + Anope::string last_quit; + Anope::string last_realname; + /* Last usermask this nick was seen on, eg user@host */ + Anope::string last_usermask; + /* Last uncloaked usermask, requires nickserv/auspex to see */ + Anope::string last_realhost; + time_t time_registered; + time_t last_seen; + /* Account this nick is tied to. Multiple nicks can be tied to a single account. */ + Serialize::Reference nc; + + /** Constructor * @param nickname The nick * @param nickcore The nickcore for this nick */ NickAlias(const Anope::string &nickname, NickCore *nickcore); - - /** Default destructor - */ ~NickAlias(); - Anope::string nick; /* Nickname */ - Anope::string last_quit; /* Last quit message */ - Anope::string last_realname; /* Last realname */ - Anope::string last_usermask; /* Last usermask */ - Anope::string last_realhost; /* Last uncloaked usermask, requires nickserv/auspex to see */ - time_t time_registered; /* When the nick was registered */ - time_t last_seen; /* When it was seen online for the last time */ - serialize_obj nc; /* I'm an alias of this */ - - Serialize::Data serialize() const anope_override; - static Serializable* unserialize(Serializable *obj, Serialize::Data &); + Serialize::Data Serialize() const anope_override; + static Serializable* Unserialize(Serializable *obj, Serialize::Data &); /** Release a nick * See the comment in users.cpp @@ -184,41 +173,67 @@ class CoreExport NickAlias : public Serializable, public Extensible, public Flag * @return the time it was created */ time_t GetVhostCreated() const; + + /** Finds a registered nick + * @param nick The nick to lookup + * @return the nick, if found + */ + static NickAlias *Find(const Anope::string &nick); }; -/* It matters that Base is here before Extensible (it is inherited by Serializable) */ -class CoreExport NickCore : public Serializable, public Extensible, public Flags +/* A registered account. Each account must have a NickAlias with the same nick as the + * account's display. + * It matters that Base is here before Extensible (it is inherited by Serializable) + */ +class CoreExport NickCore : public Serializable, public Extensible, public Flags { public: - /** Default constructor - * @param display The display nick - */ - NickCore(const Anope::string &nickdisplay); + /* Name of the account. Find(display)->nc == this. */ + Anope::string display; + /* User password in form of hashm:data */ + Anope::string pass; + Anope::string email; + /* Greet associated with the account, sometimes sent when the user joins a channel */ + Anope::string greet; + /* Locale name of the language of the user. Empty means default language */ + Anope::string language; + /* Access list, contains user@host masks of users who get certain privileges based + * on if NI_SECURE is set and what (if any) kill protection is enabled. */ + std::vector access; + /* SSL certificate list. Users who have a matching certificate may be automatically logged in */ + std::vector cert; + MemoInfo memos; - /** Default destructor + /* Nicknames registered that are grouped to this account. + * for n in aliases, n->nc == this. */ - ~NickCore(); - - std::list Users; - - Anope::string display; /* How the nick is displayed */ - Anope::string pass; /* Password of the nicks */ - Anope::string email; /* E-mail associated to the nick */ - Anope::string greet; /* Greet associated to the nick */ - Anope::string language; /* Language name */ - std::vector access; /* Access list, vector of strings */ - std::vector cert; /* ssl certificate list, vector of strings */ - MemoInfo memos; + std::list > aliases; + /* Set if this user is a services operattor. o->ot must exist. */ Oper *o; /* Unsaved data */ - uint16_t channelcount; /* Number of channels currently registered */ - time_t lastmail; /* Last time this nick record got a mail */ - std::list > aliases; /* List of aliases */ - Serialize::Data serialize() const anope_override; - static Serializable* unserialize(Serializable *obj, Serialize::Data &); + /* Number of channels registered by this account */ + uint16_t channelcount; + /* Last time an email was sent to this user */ + time_t lastmail; + /* Users online now logged into this account */ + std::list users; + + /** Constructor + * @param display The display nick + */ + NickCore(const Anope::string &nickdisplay); + ~NickCore(); + + Serialize::Data Serialize() const anope_override; + static Serializable* Unserialize(Serializable *obj, Serialize::Data &); + + /** Changes the display for this account + * @param na The new display, must be grouped to this account. + */ + void SetDisplay(const NickAlias *na); /** Checks whether this account is a services oper or not. * @return True if this account is a services oper, false otherwise. @@ -265,6 +280,14 @@ class CoreExport NickCore : public Serializable, public Extensible, public Flags */ void ClearAccess(); + /** Is the given user on this accounts access list? + * + * @param u The user + * + * @return true if the user is on the access list + */ + bool IsOnAccess(const User *u) const; + /** Add an entry to the nick's certificate list * * @param entry The fingerprint to add to the cert list @@ -304,10 +327,21 @@ class CoreExport NickCore : public Serializable, public Extensible, public Flags * Deletes all the memory allocated in the certificate list vector and then clears the vector. */ void ClearCert(); + + /** Finds an account + * @param nick The account name to find + * @return The account, if it exists + */ + static NickCore* Find(const Anope::string &nick); }; +/* A request to check if an account/password is valid. These can exist for + * extended periods of time due to some authentication modules take. + */ class CoreExport IdentifyRequest { + /* Owner of this request, used to cleanup requests if a module is unloaded + * while a reqyest us pending */ Module *owner; Anope::string account; Anope::string password; @@ -316,35 +350,47 @@ class CoreExport IdentifyRequest bool dispatched; bool success; - static std::set requests; + static std::set Requests; protected: IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass); virtual ~IdentifyRequest(); public: + /* One of these is called when the request goes through */ virtual void OnSuccess() = 0; virtual void OnFail() = 0; const Anope::string &GetAccount() const { return account; } const Anope::string &GetPassword() const { return password; } - /* Hold this request. Once held it must be Release()d later on */ + /* Holds this request. When a request is held it must be Released later + * for the request to complete. Multiple modules may hold a request at any time, + * but the request is not complete until every module has released it. If you do not + * require holding this (eg, your password check is done in this thread and immediately) + * then you don't need to hold the request before Successing it. + * @param m The module holding this request + */ void Hold(Module *m); + + /** Releases a held request + * @param m The module releaseing the hold + */ void Release(Module *m); + /** Called by modules when this IdentifyRequest has successeded successfully. + * If this request is behind held it must still be Released after calling this. + * @param m The module confirming authentication + */ void Success(Module *m); + /** Used to either finalize this request or marks + * it as dispatched and begins waiting for the module(s) + * that have holds to finish. + */ void Dispatch(); static void ModuleUnload(Module *m); }; -extern CoreExport void change_core_display(NickCore *nc); -extern CoreExport void change_core_display(NickCore *nc, const Anope::string &newdisplay); - -extern CoreExport NickAlias *findnick(const Anope::string &nick); -extern CoreExport NickCore *findcore(const Anope::string &nick); -extern CoreExport bool is_on_access(const User *u, const NickCore *nc); - #endif // ACCOUNT_H diff --git a/include/anope.h b/include/anope.h index b6033b15c..2dda6cf76 100644 --- a/include/anope.h +++ b/include/anope.h @@ -1,4 +1,5 @@ /* + * * (C) 2003-2012 Anope Team * Contact us at team@anope.org * @@ -6,6 +7,7 @@ * * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. + * */ #ifndef ANOPE_H @@ -304,11 +306,52 @@ namespace Anope static const char *const compiled = __TIME__ " " __DATE__; + /** The time Anope started. + */ + extern time_t StartTime; + + /** The value to return from main() + */ + extern int ReturnValue; + extern bool Quitting; + extern bool Restarting; + extern Anope::string QuitReason; + /** The current system time, which is pretty close to being accurate. * Use this unless you need very specific time checks */ extern CoreExport time_t CurTime; + /** The debug level we are running at. + */ + extern int Debug; + + /** Other comand line options. + */ + extern bool ReadOnly, NoFork, NoThird, NoExpire, ProtocolDebug; + + /** The root of the services installation. Usually ~/services + */ + extern Anope::string ServicesDir; + + /** Services binary name (eg services) + */ + extern Anope::string ServicesBin; + + /** Various directory paths. These can be set at runtime by command line args + */ + extern Anope::string ConfigDir; + extern Anope::string DataDir; + extern Anope::string ModuleDir; + extern Anope::string LocaleDir; + extern Anope::string LogDir; + + /** The uplink we are currently connected to + */ + extern int CurrentUplink; + + /** Various methods to determine the Anope version running + */ extern CoreExport string Version(); extern CoreExport string VersionShort(); extern CoreExport string VersionBuildString(); @@ -316,6 +359,29 @@ namespace Anope extern CoreExport int VersionMinor(); extern CoreExport int VersionPatch(); + /** Determines if we are still attached to the terminal, and can print + * messages to the user via stderr/stdout. + * @return true if still attached + */ + extern bool AtTerm(); + + /** Used to "fork" the process and go into the background during initial startup + * while we are AtTerm(). The actual fork is not done here, but earlier, and this + * simply notifys the parent via kill() to exit(). + */ + extern void Fork(); + + /** One of the first functions called, does general initialization such as reading + * command line args, loading the configuration, doing the initial fork() if necessary, + * initializating language support, loading modules, and loading databases. + * @throws CoreException if something bad went wrong + */ + extern void Init(int ac, char **av); + + /** Calls the save database event + */ + extern void SaveDatabases(); + /** Check whether two strings match. * @param str The string to check against the pattern (e.g. foobar) * @param mask The pattern to check (e.g. foo*bar) @@ -350,6 +416,20 @@ namespace Anope */ extern CoreExport void B64Decode(const string &src, string &target); + /** Encrypts what is in 'src' to 'dest' + * @param src The source string to encrypt + * @param dest The destination where the encrypted string is placed + */ + extern void Encrypt(const Anope::string &src, Anope::string &dest); + + /** Decrypts what is in 'src' to 'dest'. + * @param src The source string to decrypt + * @param dest The destination where the decrypted string is placed + * @return true if decryption was successful. This is usually not the case + * as most encryption methods we use are one way. + */ + extern bool Decrypt(const Anope::string &src, Anope::string &dest); + /** Returns a sequence of data formatted as the format argument specifies. ** After the format parameter, the function expects at least as many ** additional arguments as specified in format. @@ -368,6 +448,48 @@ namespace Anope * @return An error message */ extern CoreExport const string LastError(); + + /** Determines if a path is a file + */ + extern bool IsFile(const Anope::string &file); + + /** Converts a string into seconds + * @param s The string, eg 3d + * @return The time represented by the string, eg 259,200 + */ + extern time_t DoTime(const Anope::string &s); + + /** Retrieves a human readable string representing the time in seconds + * @param seconds The time on seconds, eg 60 + * @param nc The account to use langauge settings for to translate this string, if applicable + * @return A human readable string, eg "1 minute" + */ + extern Anope::string Duration(time_t seconds, const NickCore *nc = NULL); + + /** Generates a human readable string of type "expires in ..." + * @param expires time in seconds + * @param nc The account to use langauge settings for to translate this string, if applicable + * @return A human readable string, eg "expires in 5 days" + */ + extern Anope::string Expires(time_t seconds, const NickCore *nc = NULL); + + /** Converts a time in seconds (epoch) to a human readable format. + * @param t The time + * @param nc The account to use langauge settings for to translate this string, if applicable + * @param short_output If true, the output is just a date (eg, "Apr 12 20:18:22 2009 MSD"), else it includes the date and how long ago/from now that date is, (eg "Apr 12 20:18:22 2009 MSD (1313 days, 9 hours, 32 minutes ago)" + */ + extern Anope::string strftime(time_t t, const NickCore *nc = NULL, bool short_output = false); + + /** Normalize buffer, stripping control characters and colors + * @param A string to be parsed for control and color codes + * @return A string stripped of control and color codes + */ + extern Anope::string NormalizeBuffer(const Anope::string &); + + /** Main processing routine. Parses the message and takes the appropriate action. + * @param Raw message from the uplink + */ + extern void Process(const Anope::string &); } /** sepstream allows for splitting token seperated lists. @@ -394,23 +516,52 @@ class CoreExport sepstream /** Create a sepstream and fill it with the provided data */ sepstream(const Anope::string &source, char seperator); - virtual ~sepstream() { } /** Fetch the next token from the stream * @param token The next token from the stream is placed here * @return True if tokens still remain, false if there are none left */ - virtual bool GetToken(Anope::string &token); + bool GetToken(Anope::string &token); + + /** Gets token number 'num' from the stream + * @param token The token is placed here + * @param num The token number to featch + * @return True if the token was able to be detched + */ + bool GetToken(Anope::string &token, int num); + + /** Gets every token from this stream + * @param token Tokens are pushed back here + */ + template void GetTokens(T& token) + { + token.clear(); + Anope::string t; + while (this->GetToken(t)) + token.push_back(t); + } + + /** Gets token number 'num' from the stream and all remaining tokens. + * @param token The token is placed here + * @param num The token number to featch + * @return True if the token was able to be detched + */ + bool GetTokenRemainder(Anope::string &token, int num); + + /** Determines the number of tokens in this stream. + * @return The number of tokens in this stream + */ + int NumTokens(); /** Fetch the entire remaining stream, without tokenizing * @return The remaining part of the stream */ - virtual const Anope::string GetRemaining(); + const Anope::string GetRemaining(); /** Returns true if the end of the stream has been reached * @return True if the end of the stream has been reached, otherwise false */ - virtual bool StreamEnd(); + bool StreamEnd(); }; /** A derived form of sepstream, which seperates on commas @@ -478,14 +629,6 @@ class CoreException : public std::exception } }; -class FatalException : public CoreException -{ - public: - FatalException(const Anope::string &reason = "") : CoreException(reason) { } - - virtual ~FatalException() throw() { } -}; - class ModuleException : public CoreException { public: @@ -600,39 +743,43 @@ template inline T anope_dynamic_reinterpret_cast(O ptr) /** Class with the ability to keep flags on items, they should extend from this * where T is an enum. */ -template class Flags +template class Flags { - protected: - std::bitset Flag_Values; - const Anope::string *Flag_Strings; + std::vector flags_values; + static const Anope::string *flags_strings; public: - Flags() : Flag_Strings(NULL) { } - Flags(const Anope::string *flag_strings) : Flag_Strings(flag_strings) { } - /** Add a flag to this item - * @param Value The flag + * @param value The flag */ - void SetFlag(T Value) + void SetFlag(T value) { - Flag_Values[Value] = true; + if (value < 0) + return; + + if (static_cast(value) >= flags_values.size()) + flags_values.resize(value + 1); + flags_values[value] = true; } /** Remove a flag from this item - * @param Value The flag + * @param value The flag */ - void UnsetFlag(T Value) + void UnsetFlag(T value) { - Flag_Values[Value] = false; + if (value >= 0 && static_cast(value) < flags_values.size()) + flags_values[value] = false; } /** Check if this item has a flag - * @param Value The flag + * @param value The flag * @return true or false */ - bool HasFlag(T Value) const + bool HasFlag(T value) const { - return Flag_Values.test(Value); + if (value >= 0 && static_cast(value) < flags_values.size()) + return flags_values[value]; + return false; } /** Check how many flags are set @@ -640,14 +787,23 @@ template class Flags */ size_t FlagCount() const { - return Flag_Values.count(); + size_t c = 0; + for (unsigned i = 0; i < flags_values.size(); ++i) + if (flags_values[i]) + ++c; + return c; } /** Unset all of the flags */ void ClearFlags() { - Flag_Values.reset(); + flags_values.clear(); + } + + static const Anope::string* GetFlagStrings() + { + return flags_strings; } Anope::string ToString() const @@ -675,9 +831,9 @@ template class Flags std::vector ToVector() const { std::vector ret; - for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i) + for (unsigned i = 0; this->flags_strings && !this->flags_strings[i].empty(); ++i) if (this->HasFlag(static_cast(i))) - ret.push_back(this->Flag_Strings[i]); + ret.push_back(this->flags_strings[i]); return ret; } @@ -685,9 +841,9 @@ template class Flags { this->ClearFlags(); - for (unsigned i = 0; this->Flag_Strings && !this->Flag_Strings[i].empty(); ++i) + for (unsigned i = 0; this->flags_strings && !this->flags_strings[i].empty(); ++i) for (unsigned j = 0; j < strings.size(); ++j) - if (this->Flag_Strings[i] == strings[j]) + if (this->flags_strings[i] == strings[j]) this->SetFlag(static_cast(i)); } }; diff --git a/include/base.h b/include/base.h index c09b97400..178bb1937 100644 --- a/include/base.h +++ b/include/base.h @@ -4,6 +4,7 @@ * Copyright (C) 2008-2012 Anope Team * * Please read COPYING and README for further details. + * */ #ifndef BASE_H @@ -16,48 +17,57 @@ class CoreExport Base { /* References to this base class */ - std::set References; + std::set references; public: Base(); virtual ~Base(); - void AddReference(dynamic_reference_base *r); - void DelReference(dynamic_reference_base *r); + + /** Adds a reference to this object. Eg, when a Reference + * is created referring to this object this is called. It is used to + * cleanup references when this object is destructed. + */ + void AddReference(ReferenceBase *r); + + void DelReference(ReferenceBase *r); }; -class dynamic_reference_base +class ReferenceBase { protected: bool invalid; public: - dynamic_reference_base() : invalid(false) { } - dynamic_reference_base(const dynamic_reference_base &other) : invalid(other.invalid) { } - virtual ~dynamic_reference_base() { } + ReferenceBase() : invalid(false) { } + ReferenceBase(const ReferenceBase &other) : invalid(other.invalid) { } + virtual ~ReferenceBase() { } inline void Invalidate() { this->invalid = true; } }; +/** Used to hold pointers to objects that may be deleted. A Reference will + * no longer be valid once the object it refers is destructed. + */ template -class dynamic_reference : public dynamic_reference_base +class Reference : public ReferenceBase { protected: T *ref; public: - dynamic_reference() : ref(NULL) + Reference() : ref(NULL) { } - dynamic_reference(T *obj) : ref(obj) + Reference(T *obj) : ref(obj) { if (ref) ref->AddReference(this); } - dynamic_reference(const dynamic_reference &other) : dynamic_reference_base(other), ref(other.ref) + Reference(const Reference &other) : ReferenceBase(other), ref(other.ref) { if (operator bool()) ref->AddReference(this); } - virtual ~dynamic_reference() + virtual ~Reference() { if (operator bool()) ref->DelReference(this); @@ -105,12 +115,12 @@ class dynamic_reference : public dynamic_reference_base this->ref->AddReference(this); } - inline bool operator<(const dynamic_reference &other) const + inline bool operator<(const Reference &other) const { return this < &other; } - inline bool operator==(const dynamic_reference &other) + inline bool operator==(const Reference &other) { if (!this->invalid) return this->ref == other; diff --git a/include/bots.h b/include/bots.h index 888e8d217..3d44d08dd 100644 --- a/include/bots.h +++ b/include/bots.h @@ -1,8 +1,10 @@ /* + * * Copyright (C) 2008-2011 Robin Burchell * Copyright (C) 2008-2012 Anope Team * * Please read COPYING and README for further details. + * */ #ifndef BOTS_H @@ -16,7 +18,7 @@ typedef Anope::map botinfo_map; -extern CoreExport serialize_checker BotListByNick, BotListByUID; +extern CoreExport Serialize::Checker BotListByNick, BotListByUID; /** Flags settable on a bot */ @@ -24,8 +26,6 @@ enum BotFlag { BI_BEGIN, - /* This bot is a core bot. NickServ, ChanServ, etc */ - BI_CORE, /* This bot can only be assigned by IRCops */ BI_PRIVATE, /* This bot is defined in the config */ @@ -34,17 +34,21 @@ enum BotFlag BI_END }; -static const Anope::string BotFlagString[] = { "BEGIN", "CORE", "PRIVATE", "CONF", "" }; - -class CoreExport BotInfo : public User, public Flags, public Serializable +/* A service bot (NickServ, ChanServ, a BotServ bot, etc). */ +class CoreExport BotInfo : public User, public Flags, public Serializable { public: - time_t created; /* Birth date ;) */ - time_t lastmsg; /* Last time we said something */ - CommandInfo::map commands; /* Commands, actual name to service name */ - Anope::string botmodes; /* Modes the bot should have as configured in service:modes */ - std::vector botchannels; /* Channels the bot should be in as configured in service:channels */ - bool introduced; /* Whether or not this bot is introduced */ + time_t created; + /* Last time this bot said something (via privmsg) */ + time_t lastmsg; + /* Map of actual command names -> service name/permission required */ + CommandInfo::map commands; + /* Modes the bot should have as configured in service:modes */ + Anope::string botmodes; + /* Channels the bot should be in as configured in service:channels */ + std::vector botchannels; + /* Whether or not this bot is introduced to the network */ + bool introduced; /** Create a new bot. * @param nick The nickname to assign to the bot. @@ -59,8 +63,8 @@ class CoreExport BotInfo : public User, public Flags, public Se */ virtual ~BotInfo(); - Serialize::Data serialize() const; - static Serializable* unserialize(Serializable *obj, Serialize::Data &); + Serialize::Data Serialize() const; + static Serializable* Unserialize(Serializable *obj, Serialize::Data &); void GenerateUID(); @@ -126,11 +130,13 @@ class CoreExport BotInfo : public User, public Flags, public Se * @return A struct containing service name and permission */ CommandInfo *GetCommand(const Anope::string &cname); -}; -extern CoreExport BotInfo *findbot(const Anope::string &nick); - -extern CoreExport void bot_raw_ban(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason); -extern CoreExport void bot_raw_kick(User *requester, ChannelInfo *ci, const Anope::string &nick, const Anope::string &reason); + /** Find a bot by nick + * @param nick The nick + * @param nick_only True to only look by nick, and not by UID + * @return The bot, if it exists + */ + static BotInfo* Find(const Anope::string &nick, bool nick_only = false); +}; #endif // BOTS_H diff --git a/include/botserv.h b/include/botserv.h deleted file mode 100644 index e5ef2c8ba..000000000 --- a/include/botserv.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * (C) 2003-2012 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#ifndef BOTSERV_H -#define BOTSERV_H - -#include "anope.h" - -/* BotServ SET flags */ -enum BotServFlag -{ - BS_BEGIN, - /* BotServ won't kick ops */ - BS_DONTKICKOPS, - /* BotServ won't kick voices */ - BS_DONTKICKVOICES, - /* BotServ bot accepts fantasy commands */ - BS_FANTASY, - /* BotServ should show greets */ - BS_GREET, - /* BotServ bots are not allowed to be in this channel */ - BS_NOBOT, - /* BotServ kicks for bolds */ - BS_KICK_BOLDS, - /* BotServ kicks for colors */ - BS_KICK_COLORS, - /* BOtServ kicks for reverses */ - BS_KICK_REVERSES, - /* BotServ kicks for underlines */ - BS_KICK_UNDERLINES, - /* BotServ kicks for badwords */ - BS_KICK_BADWORDS, - /* BotServ kicks for caps */ - BS_KICK_CAPS, - /* BotServ kicks for flood */ - BS_KICK_FLOOD, - /* BotServ kicks for repeating */ - BS_KICK_REPEAT, - /* BotServ kicks for italics */ - BS_KICK_ITALICS, - /* BotServ kicks for amsgs */ - BS_KICK_AMSGS, - BS_END -}; - -const Anope::string BotServFlagStrings[] = { - "BEGIN", "DONTKICKOPS", "DONTKICKVOICES", "FANTASY", "GREET", "NOBOT", - "KICK_BOLDs", "KICK_COLORS", "KICK_REVERSES", "KICK_UNDERLINES", "KICK_BADWORDS", "KICK_CAPS", - "KICK_FLOOD", "KICK_REPEAT", "KICK_ITALICS", "KICK_AMSGS", "MSG_PRIVMSG", "MSG_NOTICE", - "MSG_NOTICEOPS", "" -}; - -/* Indices for TTB (Times To Ban) */ -enum -{ - TTB_BOLDS, - TTB_COLORS, - TTB_REVERSES, - TTB_UNDERLINES, - TTB_BADWORDS, - TTB_CAPS, - TTB_FLOOD, - TTB_REPEAT, - TTB_ITALICS, - TTB_AMSGS, - TTB_SIZE -}; - -#endif // BOTSERV_H diff --git a/include/channels.h b/include/channels.h index 99ddf06b9..5cbea5ecc 100644 --- a/include/channels.h +++ b/include/channels.h @@ -4,6 +4,7 @@ * Contact us at team@anope.org * * Please read COPYING and README for further details. + * */ #ifndef CHANNELS_H @@ -18,10 +19,12 @@ typedef Anope::hash_map channel_map; extern CoreExport channel_map ChannelList; +/* A user container, there is one of these per user per channel. */ struct UserContainer : public Extensible { User *user; - ChannelStatus *Status; + /* Status the user has in the channel */ + ChannelStatus *status; UserContainer(User *u) : user(u) { } virtual ~UserContainer() { } @@ -39,9 +42,7 @@ enum ChannelFlag CH_SYNCING }; -const Anope::string ChannelFlagString[] = { "CH_INABIT", "CH_PERSIST", "CH_SYNCING", "" }; - -class CoreExport Channel : public virtual Base, public Extensible, public Flags +class CoreExport Channel : public Base, public Extensible, public Flags { public: typedef std::multimap ModeList; @@ -51,27 +52,27 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< ModeList modes; public: - /** Default constructor - * @param name The channel name - * @param ts The time the channel was created - */ - Channel(const Anope::string &nname, time_t ts = Anope::CurTime); - - /** Default destructor - */ - ~Channel(); - - Anope::string name; /* Channel name */ - serialize_obj ci; /* Corresponding ChannelInfo */ - time_t creation_time; /* When channel was created */ - - /* List of users in the channel */ + /* Channel name */ + Anope::string name; + /* Set if this channel is registered. ci->c == this. Contains information relevant to the registered channel */ + Serialize::Reference ci; + /* When the channel was created */ + time_t creation_time; + + /* Users in the channel */ CUserList users; - Anope::string topic; /* Current topic of the channel */ - Anope::string topic_setter; /* Who set the topic */ - time_t topic_ts; /* The timestamp associated with the topic. Not necessarually anywhere close to Anope::CurTime */ - time_t topic_time; /* The actual time the topic was set, probably close to Anope::CurTime */ + /* Current topic of the channel */ + Anope::string topic; + /* Who set the topic */ + Anope::string topic_setter; + /* The timestamp associated with the topic. Not necessarually anywhere close to Anope::CurTime. + * This is the time the topic was *originally set*. When we restore the topic we want to change the TS back + * to this, but we can only do this on certain IRCds. + */ + time_t topic_ts; + /* The actual time the topic was set, probably close to Anope::CurTime */ + time_t topic_time; time_t server_modetime; /* Time of last server MODE */ time_t chanserv_modetime; /* Time of last check_modes() */ @@ -79,6 +80,16 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< int16_t chanserv_modecount; /* Number of check_mode()'s this sec */ int16_t bouncy_modes; /* Did we fail to set modes here? */ + /** Constructor + * @param name The channel name + * @param ts The time the channel was created + */ + Channel(const Anope::string &nname, time_t ts = Anope::CurTime); + + /** Destructor + */ + ~Channel(); + /** Call if we need to unset all modes and clear all user status (internally). * Only useful if we get a SJOIN with a TS older than what we have here */ @@ -94,8 +105,9 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< /** Join a user internally to the channel * @param u The user + * @return The UserContainer for the user */ - void JoinUser(User *u); + UserContainer* JoinUser(User *u); /** Remove a user internally from the channel * @param u The user @@ -118,94 +130,101 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< /** Check if a user has a status on a channel * Use the overloaded function for ChannelModeStatus* to check for no status * @param u The user - * @param Name The Mode name, eg CMODE_OP, CMODE_VOICE + * @param name The mode name, eg CMODE_OP, CMODE_VOICE * @return true or false */ - bool HasUserStatus(const User *u, ChannelModeName Name) const; + bool HasUserStatus(const User *u, ChannelModeName name) const; /** See if a channel has a mode - * @param Name The mode name + * @param name The mode name * @return The number of modes set * @param param The optional mode param */ - size_t HasMode(ChannelModeName Name, const Anope::string ¶m = ""); + size_t HasMode(ChannelModeName name, const Anope::string ¶m = ""); /** Get a list of modes on a channel - * @param Name A mode name to get the list of + * @param name A mode name to get the list of * @return a pair of iterators for the beginning and end of the list */ - std::pair GetModeList(ChannelModeName Name); + std::pair GetModeList(ChannelModeName name); /** Set a mode internally on a channel, this is not sent out to the IRCd * @param setter The setter * @param cm The mode * @param param The param - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void SetModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void SetModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool enforce_mlock = true); /** Remove a mode internally on a channel, this is not sent out to the IRCd * @param setter The Setter * @param cm The mode * @param param The param - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void RemoveModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void RemoveModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool enforce_mlock = true); /** Set a mode on a channel * @param bi The client setting the modes * @param cm The mode * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void SetMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m = "", bool enforce_mlock = true); /** * Set a mode on a channel * @param bi The client setting the modes - * @param Name The mode name + * @param name The mode name * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void SetMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m = "", bool EnforceMLock = true); + void SetMode(BotInfo *bi, ChannelModeName name, const Anope::string ¶m = "", bool enforce_mlock = true); /** Remove a mode from a channel * @param bi The client setting the modes * @param cm The mode * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void RemoveMode(BotInfo *bi, ChannelMode *cm, const Anope::string ¶m = "", bool enforce_mlock = true); /** * Remove a mode from a channel * @param bi The client setting the modes - * @param Name The mode name + * @param name The mode name * @param param Optional param arg for the mode - * @param EnforceMLock true if mlocks should be enforced, false to override mlock + * @param enforce_mlock true if mlocks should be enforced, false to override mlock */ - void RemoveMode(BotInfo *bi, ChannelModeName Name, const Anope::string ¶m = "", bool EnforceMLock = true); + void RemoveMode(BotInfo *bi, ChannelModeName name, const Anope::string ¶m = "", bool enforce_mlock = true); - /** Get a param from the channel - * @param Name The mode - * @param Target a string to put the param into - * @return true on success + /** Get a modes parameter for the channel + * @param name The mode + * @param target a string to put the param into + * @return true if the parameter was fetched, false if on error (mode not set) etc. */ - bool GetParam(ChannelModeName Name, Anope::string &Target) const; + bool GetParam(ChannelModeName name, Anope::string &target) const; /** Set a string of modes on the channel * @param bi The client setting the modes - * @param EnforceMLock Should mlock be enforced on this mode change + * @param enforce_mlock Should mlock be enforced on this mode change * @param cmodes The modes to set */ - void SetModes(BotInfo *bi, bool EnforceMLock, const char *cmodes, ...); + void SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...); /** Set a string of modes internally on a channel * @param source The setter * @param mode the modes - * @param EnforceMLock true to enforce mlock + * @param enforce_mlock true to enforce mlock + */ + void SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts = 0, bool enforce_mlock = true); + + /** Does the given user match the given list? (CMODE_BAN, CMODE_EXCEPT, etc, a list mode) + * @param u The user + * @param list The mode of the list to check (eg CMODE_BAN) + * @return true if the user matches the list */ - void SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts = 0, bool EnforceMLock = true); + bool MatchesList(User *u, ChannelModeName list); /** Kick a user from a channel internally * @param source The sender of the kick @@ -246,12 +265,26 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< /** Hold the channel open using ChanServ */ void Hold(); -}; -extern CoreExport Channel *findchan(const Anope::string &chan); + /** Set the correct modes, or remove the ones granted without permission, + * for the specified user. + * @param user The user to give/remove modes to/from + * @param give_modes if true modes may be given to the user + * @param check_noop if true, CI_NOAUTOOP is checked before giving modes + */ + void SetCorrectModes(User *u, bool give_mode, bool check_noop); -extern CoreExport User *nc_on_chan(Channel *c, const NickCore *nc); + /** Unbans a user from this channel. + * @param u The user to unban + * @param full Whether or not to match using the user's real host and IP + */ + void Unban(const User *u, bool full = false); -extern CoreExport void chan_set_correct_modes(const User *user, Channel *c, int give_modes, bool check_noop); + /** Finds a channel + * @param name The channel to find + * @return The channel, if found + */ + static Channel* Find(const Anope::string &name); +}; #endif // CHANNELS_H diff --git a/include/commands.h b/include/commands.h index 333d6882a..5c8664147 100644 --- a/include/commands.h +++ b/include/commands.h @@ -22,20 +22,20 @@ enum CommandFlag CFLAG_STRIP_CHANNEL }; -const Anope::string CommandFlagStrings[] = { - "CFLAG_ALLOW_UNREGISTERED", - "CFLAG_STRIP_CHANNEL", - "" -}; - +/* Used in BotInfo::commands */ struct CommandInfo { typedef Anope::map map; + /* Service name of the command */ Anope::string name; + /* Permission required to execute the command */ Anope::string permission; }; +/* Where the replies from commands go to. User inheits from this and is the normal + * source of a CommandReply + */ struct CommandReply { virtual void SendMessage(const BotInfo *source, const Anope::string &msg) = 0; @@ -47,16 +47,16 @@ class CoreExport CommandSource /* The nick executing the command */ Anope::string nick; /* User executing the command, may be NULL */ - dynamic_reference u; + Reference u; public: /* The account executing the command */ - dynamic_reference nc; + Reference nc; /* Where the reply should go */ CommandReply *reply; /* Channel the command was executed on (fantasy) */ - dynamic_reference c; + Reference c; /* The service this command is on */ - dynamic_reference service; + Reference service; /* The actual name of the command being executed */ Anope::string command; /* The permission of the command being executed */ @@ -88,9 +88,9 @@ class CoreExport Command : public Service, public Flags public: /* Maximum paramaters accepted by this command */ - size_t MaxParams; + size_t max_params; /* Minimum parameters required to use this command */ - size_t MinParams; + size_t min_params; /* Module which owns us */ Module *module; diff --git a/include/config.h b/include/config.h index 86a232485..ad772033d 100644 --- a/include/config.h +++ b/include/config.h @@ -8,7 +8,6 @@ * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. * - * */ #ifndef CONFIG_H @@ -207,23 +206,6 @@ typedef bool (*MultiValidator)(ServerConfig *, const Anope::string &, const Anop */ typedef bool (*MultiNotify)(ServerConfig *, const Anope::string &); -bool ValidateNotEmpty(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateNotZero(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidatePort(ServerConfig *, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateGuestPrefix(ServerConfig *conf, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateBantype(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data); -bool ValidateChanServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateMemoServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateBotServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateHostServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateLimitSessions(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateOperServ(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateGlobal(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateNickLen(ServerConfig *, const Anope::string &, const Anope::string &, ValueItem &data); -bool ValidateMail(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); -bool ValidateGlobalOnCycle(ServerConfig *config, const Anope::string &tag, const Anope::string &value, ValueItem &data); - /** Represents a configuration file */ class ConfigurationFile @@ -463,8 +445,6 @@ class CoreExport ServerConfig bool UseServerSideTopicLock; /* Default botmodes on channels, defaults to ao */ Anope::string BotModes; - /* THe actual modes */ - ChannelStatus BotModeList; /* How long to wait between connection attempts */ int RetryWait; /* If services should hide unprivileged commands */ @@ -517,7 +497,7 @@ class CoreExport ServerConfig /* Don't allow nicks to use /ns group to regroup nicks */ bool NSNoGroupChange; /* Default flags for newly registered nicks */ - Flags NSDefFlags; + Flags NSDefFlags; /* All languages Anope is aware about */ Anope::string Languages; /* Default language used by services */ @@ -578,7 +558,7 @@ class CoreExport ServerConfig /* Core ChanServ modules */ Anope::string ChanCoreModules; /* Default flags for newly registered channels */ - Flags CSDefFlags; + Flags CSDefFlags; /* Max number of channels a user can own */ unsigned CSMaxReg; /* Time before a channel expires */ @@ -741,7 +721,7 @@ class ConfigException : public CoreException #define CONF_FILE_NOT_FOUND 0x000200 /** Allows reading of values from configuration files - * This class allows a module to read from either the main configuration file (inspircd.conf) or from + * This class allows a module to read from either the main configuration file (services.conf) or from * a module-specified configuration file. It may either be instantiated with one parameter or none. * Constructing the class using one parameter allows you to specify a path to your own configuration * file, otherwise, inspircd.conf is read. @@ -836,7 +816,7 @@ class CoreExport ConfigReader int EnumerateValues(const Anope::string &, int); }; -extern ConfigurationFile services_conf; +extern ConfigurationFile ServicesConf; extern CoreExport ServerConfig *Config; #endif // CONFIG_H diff --git a/include/defs.h b/include/defs.h index ed6795142..437f0f08d 100644 --- a/include/defs.h +++ b/include/defs.h @@ -23,21 +23,21 @@ class ClientSocket; class Command; class CommandSource; class ConnectionSocket; -class DNSPacket; -class dynamic_reference_base; +namespace DNS { class Packet; } class Entry; class IdentifyRequest; class InfoFormatter; +class IRCDProto; class ListenSocket; class Log; class LogInfo; class Memo; -class Message; class MessageSource; class Module; class NickAlias; class NickCore; class OperType; +class ReferenceBase; class Regex; class Serializable; class Server; @@ -48,7 +48,7 @@ class User; class XLine; class XLineManager; struct BadWord; -struct DNSQuery; +namespace DNS { struct Query; } struct Exception; struct MemoInfo; struct ModeLock; diff --git a/include/dns.h b/include/dns.h index 64067107b..fee9da8a9 100644 --- a/include/dns.h +++ b/include/dns.h @@ -8,260 +8,271 @@ * Based on the original code of Epona by Lara. * Based on the original code of Services by Andy Church. * - * */ - + #ifndef DNS_H #define DNS_H #include "sockets.h" #include "timers.h" -#include "extern.h" #include "config.h" - -/** Valid query types - */ -enum QueryType -{ - /* Nothing */ - DNS_QUERY_NONE, - /* A simple A lookup */ - DNS_QUERY_A = 1, - /* An authoritative name server */ - DNS_QUERY_NS = 2, - /* A CNAME lookup */ - DNS_QUERY_CNAME = 5, - /* Start of a zone of authority */ - DNS_QUERY_SOA = 6, - /* Reverse DNS lookup */ - DNS_QUERY_PTR = 12, - /* IPv6 AAAA lookup */ - DNS_QUERY_AAAA = 28, - /* Zone transfer */ - DNS_QUERY_AXFR = 252 -}; - -/** Flags that can be AND'd into DNSPacket::flags to receive certain values - */ -enum -{ - DNS_QUERYFLAGS_QR = 0x8000, - DNS_QUERYFLAGS_OPCODE = 0x7800, - DNS_QUERYFLAGS_AA = 0x400, - DBS_QUERYFLAGS_TC = 0x200, - DNS_QUERYFLAGS_RD = 0x100, - DNS_QUERYFLAGS_RA = 0x80, - DNS_QUERYFLAGS_Z = 0x70, - DNS_QUERYFLAGS_RCODE = 0xF -}; - -enum DNSError -{ - DNS_ERROR_NONE, - DNS_ERROR_UNKNOWN, - DNS_ERROR_UNLOADED, - DNS_ERROR_TIMEOUT, - DNS_ERROR_NOT_AN_ANSWER, - DNS_ERROR_NONSTANDARD_QUERY, - DNS_ERROR_FORMAT_ERROR, - DNS_ERROR_SERVER_FAILURE, - DNS_ERROR_DOMAIN_NOT_FOUND, - DNS_ERROR_NOT_IMPLEMENTED, - DNS_ERROR_REFUSED, - DNS_ERROR_NO_RECORDS, - DNS_ERROR_INVALIDTYPE -}; - - -struct CoreExport Question -{ - Anope::string name; - QueryType type; - unsigned short qclass; - - Question(); - Question(const Anope::string &, QueryType, unsigned short = 1); -}; - -struct CoreExport ResourceRecord : public Question -{ - unsigned int ttl; - Anope::string rdata; - time_t created; - - ResourceRecord(const Anope::string &, QueryType, unsigned short = 1); - ResourceRecord(const Question &); -}; - -struct CoreExport DNSQuery -{ - std::vector questions; - std::vector answers, authorities, additional; - DNSError error; - - DNSQuery(); - DNSQuery(const Question &q); -}; - -/** The request - */ -class CoreExport DNSRequest : public Timer, public Question -{ - /* Use result cache if available */ - bool use_cache; - - public: - /* Request id */ - unsigned short id; - /* Creator of this request */ - Module *creator; - - DNSRequest(const Anope::string &addr, QueryType qt, bool cache = false, Module *c = NULL); - - virtual ~DNSRequest(); - - void Process(); - - virtual void OnLookupComplete(const DNSQuery *r) = 0; - - virtual void OnError(const DNSQuery *r); - void Tick(time_t) anope_override; -}; - -/** A full packet sent or recieved to/from the nameserver - */ -class DNSPacket : public DNSQuery +namespace DNS { - static const int DNS_POINTER = 0xC0; - static const int DNS_LABEL = 0x3F; - - void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name); - Anope::string UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos); - Question UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos); - ResourceRecord UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &poss); - public: - static const int HEADER_LENGTH = 12; - - /* Source or destination of the packet */ - sockaddrs addr; - /* ID for this packet */ - unsigned short id; - /* Flags on the packet */ - unsigned short flags; - - DNSPacket(sockaddrs *a); - void Fill(const unsigned char *input, const unsigned short len); - unsigned short Pack(unsigned char *output, unsigned short output_size); -}; - -/** DNS manager - */ -class CoreExport DNSManager : public Timer -{ - class ReplySocket : public virtual Socket + /** Valid query types + */ + enum QueryType + { + /* Nothing */ + QUERY_NONE, + /* A simple A lookup */ + QUERY_A = 1, + /* An authoritative name server */ + QUERY_NS = 2, + /* A CNAME lookup */ + QUERY_CNAME = 5, + /* Start of a zone of authority */ + QUERY_SOA = 6, + /* Reverse DNS lookup */ + QUERY_PTR = 12, + /* IPv6 AAAA lookup */ + QUERY_AAAA = 28, + /* Zone transfer */ + QUERY_AXFR = 252 + }; + + /** Flags that can be AND'd into DNSPacket::flags to receive certain values + */ + enum { + QUERYFLAGS_QR = 0x8000, + QUERYFLAGS_OPCODE = 0x7800, + QUERYFLAGS_AA = 0x400, + QUERYFLAGS_TC = 0x200, + QUERYFLAGS_RD = 0x100, + QUERYFLAGS_RA = 0x80, + QUERYFLAGS_Z = 0x70, + QUERYFLAGS_RCODE = 0xF + }; + + enum Error + { + ERROR_NONE, + ERROR_UNKNOWN, + ERROR_UNLOADED, + ERROR_TIMEOUT, + ERROR_NOT_AN_ANSWER, + ERROR_NONSTANDARD_QUERY, + ERROR_FORMAT_ERROR, + ERROR_SERVER_FAILURE, + ERROR_DOMAIN_NOT_FOUND, + ERROR_NOT_IMPLEMENTED, + ERROR_REFUSED, + ERROR_NO_RECORDS, + ERROR_INVALIDTYPE + }; + + + struct CoreExport Question + { + Anope::string name; + QueryType type; + unsigned short qclass; + + Question(); + Question(const Anope::string &, QueryType, unsigned short = 1); + }; + + struct CoreExport ResourceRecord : public Question + { + unsigned int ttl; + Anope::string rdata; + time_t created; + + ResourceRecord(const Anope::string &, QueryType, unsigned short = 1); + ResourceRecord(const Question &); + }; + + struct CoreExport Query + { + std::vector questions; + std::vector answers, authorities, additional; + Error error; + + Query(); + Query(const Question &q); + }; + + /** A DNS query. + */ + class CoreExport Request : public Timer, public Question + { + /* Use result cache if available */ + bool use_cache; + public: - virtual ~ReplySocket() { } - virtual void Reply(DNSPacket *p) = 0; + /* Request id */ + unsigned short id; + /* Creator of this request */ + Module *creator; + + Request(const Anope::string &addr, QueryType qt, bool cache = false, Module *c = NULL); + virtual ~Request(); + + void Process(); + + /** Called when this request succeeds + * @param r The query sent back from the nameserver + */ + virtual void OnLookupComplete(const Query *r) = 0; + + /** Called when this request fails or times out. + * @param r The query sent back from the nameserver, check the error code. + */ + virtual void OnError(const Query *r); + + /** Used to time out the query, Calls OnError and lets the TimerManager + * delete this request. + */ + void Tick(time_t) anope_override; }; - - /* Listens for TCP requests */ - class TCPSocket : public ListenSocket + + /** A full packet sent or recieved to/from the nameserver + */ + class Packet : public Query { - /* A TCP client */ - class Client : public ClientSocket, public Timer, public ReplySocket + static const int POINTER = 0xC0; + static const int LABEL = 0x3F; + + void PackName(unsigned char *output, unsigned short output_size, unsigned short &pos, const Anope::string &name); + Anope::string UnpackName(const unsigned char *input, unsigned short input_size, unsigned short &pos); + + Question UnpackQuestion(const unsigned char *input, unsigned short input_size, unsigned short &pos); + ResourceRecord UnpackResourceRecord(const unsigned char *input, unsigned short input_size, unsigned short &poss); + public: + static const int HEADER_LENGTH = 12; + + /* Source or destination of the packet */ + sockaddrs addr; + /* ID for this packet */ + unsigned short id; + /* Flags on the packet */ + unsigned short flags; + + Packet(sockaddrs *a); + void Fill(const unsigned char *input, const unsigned short len); + unsigned short Pack(unsigned char *output, unsigned short output_size); + }; + + /** DNS manager + */ + class CoreExport Manager : public Timer + { + class ReplySocket : public virtual Socket { - TCPSocket *tcpsock; - DNSPacket *packet; - unsigned char packet_buffer[524]; - int length; - public: - Client(TCPSocket *ls, int fd, const sockaddrs &addr); - ~Client(); - - /* Times out after a few seconds */ - void Tick(time_t) anope_override { } - void Reply(DNSPacket *p) anope_override; + virtual ~ReplySocket() { } + virtual void Reply(Packet *p) = 0; + }; + + /* Listens for TCP requests */ + class TCPSocket : public ListenSocket + { + /* A TCP client */ + class Client : public ClientSocket, public Timer, public ReplySocket + { + TCPSocket *tcpsock; + Packet *packet; + unsigned char packet_buffer[524]; + int length; + + public: + Client(TCPSocket *ls, int fd, const sockaddrs &addr); + ~Client(); + + /* Times out after a few seconds */ + void Tick(time_t) anope_override { } + void Reply(Packet *p) anope_override; + bool ProcessRead() anope_override; + bool ProcessWrite() anope_override; + }; + + public: + TCPSocket(const Anope::string &ip, int port); + + ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_override; + }; + + /* Listens for UDP requests */ + class UDPSocket : public ReplySocket + { + std::deque packets; + public: + + UDPSocket(const Anope::string &ip, int port); + ~UDPSocket(); + + void Reply(Packet *p) anope_override; + + std::deque& GetPackets() { return packets; } + bool ProcessRead() anope_override; + bool ProcessWrite() anope_override; }; - - public: - TCPSocket(const Anope::string &ip, int port); - - ClientSocket *OnAccept(int fd, const sockaddrs &addr) anope_override; - }; - - /* Listens for UDP requests */ - class UDPSocket : public ReplySocket - { - std::deque packets; + + typedef std::multimap cache_map; + cache_map cache; + + bool listen; + uint32_t serial; + public: - - UDPSocket(const Anope::string &ip, int port); - ~UDPSocket(); - - void Reply(DNSPacket *p) anope_override; - - std::deque& GetPackets() { return packets; } - - bool ProcessRead() anope_override; - - bool ProcessWrite() anope_override; + TCPSocket *tcpsock; + UDPSocket *udpsock; + + sockaddrs addrs; + std::map requests; + + Manager(const Anope::string &nameserver, const Anope::string &ip, int port); + ~Manager(); + + bool HandlePacket(ReplySocket *s, const unsigned char *const data, int len, sockaddrs *from); + + /** Add a record to the dns cache + * @param r The record + */ + void AddCache(Query &r); +