-/* +------------------------------------+
- * | Inspire Internet Relay Chat Daemon |
- * +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
*
- * InspIRCd: (C) 2002-2009 InspIRCd Development Team
- * See: http://wiki.inspircd.org/Credits
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ * Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
+ * Copyright (C) 2003-2007 Craig Edwards <craigedwards@brainbox.cc>
+ * Copyright (C) 2007 Burlex <???@???>
+ * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
*
- * This program is free but copyrighted software; see
- * the file COPYING for details.
+ * 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
+ * License as published by the Free Software Foundation, version 2.
*
- * ---------------------------------------------------
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __USERS_H__
-#define __USERS_H__
+
+#ifndef USERS_H
+#define USERS_H
#include "socket.h"
#include "inspsocket.h"
/** connect:allow */
CC_ALLOW = 0,
/** connect:deny */
- CC_DENY = 1
+ CC_DENY = 1,
+ /** named connect block (for opers, etc) */
+ CC_NAMED = 2
};
/** RFC1459 channel modes
REG_ALL = 7 /* REG_NICKUSER plus next bit along */
};
-/* Required forward declaration */
-class Channel;
-class UserResolver;
-struct ConfigTag;
-class OperInfo;
+enum UserType {
+ USERTYPE_LOCAL = 1,
+ USERTYPE_REMOTE = 2,
+ USERTYPE_SERVER = 3
+};
/** Holds information relevent to <connect allow> and <connect deny> tags in the config file.
*/
*/
char type;
+ /** True if this class uses fake lag to manage flood, false if it kills */
+ bool fakelag;
+
/** Connect class name
*/
std::string name;
*/
unsigned int pingtime;
- /** (Optional) Password for this line
- */
- std::string pass;
-
- /** (Optional) Hash Method for this line
- */
- std::string hash;
-
/** Maximum size of sendq for users in this class (bytes)
* Users cannot send commands if they go over this limit
*/
/** Seconds worth of penalty before penalty system activates
*/
- unsigned long penaltythreshold;
+ unsigned int penaltythreshold;
+
+ /** Maximum rate of commands (units: millicommands per second) */
+ unsigned int commandrate;
/** Local max when connecting by this connection class
*/
*/
unsigned long maxglobal;
- /** Max channels for this class
+ /** True if max connections for this class is hit and a warning is wanted
*/
- unsigned int maxchans;
+ bool maxconnwarn;
- /** Port number this connect class applies to
+ /** Max channels for this class
*/
- int port;
+ unsigned int maxchans;
/** How many users may be in this connect class before they are refused?
* (0 = no limit = default)
/** Create a new connect class with inherited settings.
*/
ConnectClass(ConfigTag* tag, char type, const std::string& mask, const ConnectClass& parent);
-
+
/** Update the settings in this block to match the given block */
void Update(const ConnectClass* newSettings);
-
const std::string& GetName() { return name; }
- const std::string& GetPass() { return pass; }
const std::string& GetHost() { return host; }
- const int GetPort() { return port; }
-
+
/** Returns the registration timeout
*/
time_t GetRegTimeout()
/** Returns the penalty threshold value
*/
- unsigned long GetPenaltyThreshold()
+ unsigned int GetPenaltyThreshold()
{
- return penaltythreshold;
+ return penaltythreshold ? penaltythreshold : (fakelag ? 10 : 20);
}
- /** Returusn the maximum number of local sessions
+ unsigned int GetCommandRate()
+ {
+ return commandrate ? commandrate : 1000;
+ }
+
+ /** Return the maximum number of local sessions
*/
unsigned long GetMaxLocal()
{
}
};
-/** Holds a complete list of all channels to which a user has been invited and has not yet joined, and the time at which they'll expire.
- */
-CoreExport typedef std::vector< std::pair<irc::string, time_t> > InvitedList;
-
-/** Holds a complete list of all allow and deny tags from the configuration file (connection classes)
- */
-CoreExport typedef std::vector<reference<ConnectClass> > ClassVector;
-
-/** Typedef for the list of user-channel records for a user
- */
-CoreExport typedef std::set<Channel*> UserChanList;
-
-/** Shorthand for an iterator into a UserChanList
- */
-CoreExport typedef UserChanList::iterator UCListIter;
-
-/* Required forward declaration
- */
-class User;
-
/** Holds all information about a user
* This class stores all information about a user connected to the irc server. Everything about a
* connection is stored here primarily, from the user's socket ID (file descriptor) through to the
* user's nickname and hostname.
*/
-class CoreExport User : public StreamSocket
+class CoreExport User : public Extensible
{
private:
/** Cached nick!ident@dhost value using the displayed hostname
*/
std::string cachedip;
- /** When we erase the user (in the destructor),
- * we call this method to subtract one from all
- * mode characters this user is making use of.
- */
- void DecrementModes();
public:
/** Hostname of connection.
time_t idle_lastmsg;
/** Client address that the user is connected from.
- * Do not modify this value directly, use SetClientIP() to change it
+ * Do not modify this value directly, use SetClientIP() to change it.
* Port is not valid for remote users.
*/
irc::sockets::sockaddrs client_sa;
/** The user's unique identifier.
* This is the unique identifier which the user has across the network.
*/
- std::string uuid;
+ const std::string uuid;
/** The users ident reply.
* Two characters are added to the user-defined limit to compensate for the tilde etc.
/** The server the user is connected to.
*/
- std::string server;
+ const std::string server;
/** The user's away message.
* If this string is empty, the user is not marked as away.
*/
unsigned int quitting:1;
+ /** Recursion fix: user is out of SendQ and will be quit as soon as possible.
+ * This can't be handled normally because QuitUser itself calls Write on other
+ * users, which could trigger their SendQ to overrun.
+ */
+ unsigned int quitting_sendq:1;
+
/** This is true if the user matched an exception (E:Line). It is used to save time on ban checks.
*/
unsigned int exempt:1;
*/
unsigned int lastping:1;
+ /** What type of user is this? */
+ const unsigned int usertype:2;
+
/** Get client IP string from sockaddr, using static internal buffer
* @return The IP string
*/
const char* GetIPString();
+ /** Get CIDR mask, using default range, for this user
+ */
+ irc::sockets::cidr_mask GetCIDRMask();
+
/** Sets the client IP for this user
* @return true if the conversion was successful
*/
bool SetClientIP(const char* sip);
- /** Get a CIDR mask from the IP of this user, using a static internal buffer.
- * e.g., GetCIDRMask(16) for 223.254.214.52 returns 223.254.0.0/16
- * This may be used for CIDR clone detection, etc.
- *
- * (XXX, brief note: when we do the sockets rewrite, this should move down a
- * level so it may be used on more derived objects. -- w00t)
- */
- const char *GetCIDRMask(int range);
-
- /** Default constructor
+ /** Constructor
* @throw CoreException if the UID allocated to the user already exists
- * @param Instance Creator instance
- * @param uid User UUID, or empty to allocate one automatically
*/
- User(const std::string &uid);
+ User(const std::string &uid, const std::string& srv, int objtype);
/** Check if the user matches a G or K line, and disconnect them if they do.
* @param doZline True if ZLines should be checked (if IP has changed since initial connect)
* on the server, in nick!ident&at;host form.
* @return The full masked host of the user
*/
- virtual const std::string GetFullHost();
+ virtual const std::string& GetFullHost();
/** Returns the full real host of the user
* This member function returns the hostname of the user as seen by other users
* e.g. through a module, then this method will ignore it and return the true hostname.
* @return The full real host of the user
*/
- virtual const std::string GetFullRealHost();
+ virtual const std::string& GetFullRealHost();
/** This clears any cached results that are used for GetFullRealHost() etc.
* The results of these calls are cached as generating them can be generally expensive.
*/
void Oper(OperInfo* info);
- /** Change this users hash key to a new string.
- * You should not call this function directly. It is used by the core
- * to update the users hash entry on a nickchange.
- * @param New new user_hash key
- * @return Pointer to User in hash (usually 'this')
- */
- User* UpdateNickHash(const char* New);
-
/** Force a nickname change.
* If the nickname change fails (for example, because the nick in question
* already exists) this function will return false, and you must then either
* @param newnick The nickname to change to
* @return True if the nickchange was successful.
*/
- bool ForceNickChange(const char* newnick);
+ inline bool ForceNickChange(const char* newnick) { return ChangeNick(newnick, true); }
/** Oper down.
* This will clear the +o usermode and unset the user's oper type
*/
bool ChangeName(const char* gecos);
+ /** Change a user's nick
+ * @param newnick The new nick
+ * @param force True if the change is being forced (should not be blocked by modes like +N)
+ * @return True if the change succeeded
+ */
+ bool ChangeNick(const std::string& newnick, bool force = false);
+
/** Send a command to all local users from this user
* The command given must be able to send text with the
* first parameter as a servermask (e.g. $*), so basically
*/
virtual ConnectClass* GetClass();
- /** Show the message of the day to this user
- */
- void ShowMOTD();
-
- /** Show the server RULES file to this user
- */
- void ShowRULES();
-
- virtual void OnDataReady();
- virtual void OnError(BufferedSocketError error);
/** Default destructor
*/
virtual ~User();
virtual CullResult cull();
};
-/** Represents a non-local user.
- * (in fact, any FD less than -1 does)
- */
-#define FD_MAGIC_NUMBER -42
-/** Represents a fake user (i.e. a server)
- */
-#define FD_FAKEUSER_NUMBER -7
+class CoreExport UserIOHandler : public StreamSocket
+{
+ public:
+ LocalUser* const user;
+ UserIOHandler(LocalUser* me) : user(me) {}
+ void OnDataReady();
+ void OnError(BufferedSocketError error);
+
+ /** Adds to the user's write buffer.
+ * You may add any amount of text up to this users sendq value, if you exceed the
+ * sendq value, the user will be removed, and further buffer adds will be dropped.
+ * @param data The data to add to the write buffer
+ */
+ void AddWriteBuf(const std::string &data);
+};
+
+typedef unsigned int already_sent_t;
class CoreExport LocalUser : public User
{
*/
InvitedList invites;
- std::set<std::string> *AllowedOperCommands;
- std::set<std::string> *AllowedPrivs;
-
- /** Allowed user modes from oper classes. */
- std::bitset<64> AllowedUserModes;
-
- /** Allowed channel modes from oper classes. */
- std::bitset<64> AllowedChanModes;
-
public:
- LocalUser();
+ LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
CullResult cull();
+ UserIOHandler eh;
+
/** Stats counter for bytes inbound
*/
int bytes_in;
*/
time_t nping;
- /** This value contains how far into the penalty threshold the user is. Once its over
- * the penalty threshold then commands are held and processed on-timer.
+ /** This value contains how far into the penalty threshold the user is.
+ * This is used either to enable fake lag or for excess flood quits
*/
- int Penalty;
+ unsigned int CommandFloodPenalty;
+
+ static already_sent_t already_sent_id;
+ already_sent_t already_sent;
/** Stored reverse lookup from res_forward. Should not be used after resolution.
*/
*/
void SetClass(const std::string &explicit_name = "");
- void OnDataReady();
void SendText(const std::string& line);
void Write(const std::string& text);
void Write(const char*, ...) CUSTOM_PRINTF(2, 3);
- /** Adds to the user's write buffer.
- * You may add any amount of text up to this users sendq value, if you exceed the
- * sendq value, the user will be removed, and further buffer adds will be dropped.
- * @param data The data to add to the write buffer
- */
- void AddWriteBuf(const std::string &data);
-
/** Returns the list of channels this user has been invited to but has not yet joined.
* @return A list of channels the user is invited to
*/
* @return True if the user can set or unset this mode.
*/
bool HasModePermission(unsigned char mode, ModeType type);
-
- void OperInternal();
- void UnOperInternal();
};
class CoreExport RemoteUser : public User
{
public:
- RemoteUser(const std::string& uid) : User(uid)
+ RemoteUser(const std::string& uid, const std::string& srv) : User(uid, srv, USERTYPE_REMOTE)
{
- SetFd(FD_MAGIC_NUMBER);
}
virtual void SendText(const std::string& line);
};
class CoreExport FakeUser : public User
{
public:
- FakeUser(const std::string &uid) : User(uid)
+ FakeUser(const std::string &uid, const std::string& srv) : User(uid, srv, USERTYPE_SERVER)
{
- SetFd(FD_FAKEUSER_NUMBER);
+ nick = srv;
}
+ virtual CullResult cull();
virtual void SendText(const std::string& line);
- virtual const std::string GetFullHost();
- virtual const std::string GetFullRealHost();
- void SetFakeServer(std::string name);
+ virtual const std::string& GetFullHost();
+ virtual const std::string& GetFullRealHost();
};
/* Faster than dynamic_cast */
/** Is a local user */
inline LocalUser* IS_LOCAL(User* u)
{
- return u->GetFd() > -1 ? static_cast<LocalUser*>(u) : NULL;
+ return u->usertype == USERTYPE_LOCAL ? static_cast<LocalUser*>(u) : NULL;
}
/** Is a remote user */
inline RemoteUser* IS_REMOTE(User* u)
{
- return u->GetFd() == FD_MAGIC_NUMBER ? static_cast<RemoteUser*>(u) : NULL;
+ return u->usertype == USERTYPE_REMOTE ? static_cast<RemoteUser*>(u) : NULL;
}
/** Is a server fakeuser */
inline FakeUser* IS_SERVER(User* u)
{
- return u->GetFd() == FD_FAKEUSER_NUMBER ? static_cast<FakeUser*>(u) : NULL;
+ return u->usertype == USERTYPE_SERVER ? static_cast<FakeUser*>(u) : NULL;
}
/** Is an oper */
#define IS_OPER(x) (x->oper)
class CoreExport UserResolver : public Resolver
{
private:
- /** User this class is 'attached' to.
- */
- LocalUser* bound_user;
- /** File descriptor teh lookup is bound to
- */
- int bound_fd;
+ /** UUID we are looking up */
+ std::string uuid;
/** True if the lookup is forward, false if is a reverse lookup
*/
bool fwd;