summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/base.h4
-rw-r--r--include/cull_list.h9
-rw-r--r--include/inspircd.h19
-rw-r--r--include/inspsocket.h327
-rw-r--r--include/modules.h59
-rw-r--r--include/socket.h2
-rw-r--r--include/socketengine.h84
-rw-r--r--include/socketengines/socketengine_epoll.h9
-rw-r--r--include/socketengines/socketengine_iocp.h6
-rw-r--r--include/socketengines/socketengine_kqueue.h9
-rw-r--r--include/socketengines/socketengine_poll.h7
-rw-r--r--include/socketengines/socketengine_ports.h8
-rw-r--r--include/socketengines/socketengine_select.h8
-rw-r--r--include/users.h75
14 files changed, 165 insertions, 461 deletions
diff --git a/include/base.h b/include/base.h
index ab52545f9..b66051caf 100644
--- a/include/base.h
+++ b/include/base.h
@@ -28,7 +28,9 @@ class CoreExport classbase
public:
classbase();
- virtual ~classbase() { }
+ // Called just prior to destruction via cull list
+ virtual void cull();
+ virtual ~classbase();
};
/** BoolSet is a utility class designed to hold eight bools in a bitmask.
diff --git a/include/cull_list.h b/include/cull_list.h
index 8c3827642..bd2fb45da 100644
--- a/include/cull_list.h
+++ b/include/cull_list.h
@@ -19,17 +19,14 @@
* avoid problems with references to deleted pointers if an object were deleted
* during execution.
*/
-class CoreExport CullList : public classbase
+class CoreExport CullList
{
- private:
- std::vector<classbase*> list;
+ std::set<classbase*> list;
public:
- CullList() {}
-
/** Adds an item to the cull list
*/
- void AddItem(classbase* item) { list.push_back(item); }
+ void AddItem(classbase* item) { list.insert(item); }
/** Applies the cull list (deletes the contents)
*/
diff --git a/include/inspircd.h b/include/inspircd.h
index b927f0b1b..72e49c09a 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -277,7 +277,6 @@ class serverstats : public classbase
class InspIRCd;
-DEFINE_HANDLER1(ProcessUserHandler, void, User*);
DEFINE_HANDLER2(IsNickHandler, bool, const char*, size_t);
DEFINE_HANDLER1(IsIdentHandler, bool, const char*);
DEFINE_HANDLER1(FloodQuitUserHandler, void, User*);
@@ -386,7 +385,6 @@ class CoreExport InspIRCd : public classbase
/**** Functors ****/
- ProcessUserHandler HandleProcessUser;
IsNickHandler HandleIsNick;
IsIdentHandler HandleIsIdent;
FloodQuitUserHandler HandleFloodQuitUser;
@@ -394,11 +392,6 @@ class CoreExport InspIRCd : public classbase
IsSIDHandler HandleIsSID;
RehashHandler HandleRehash;
- /** BufferedSocket classes pending deletion after being closed.
- * We don't delete these immediately as this may cause a segmentation fault.
- */
- std::map<BufferedSocket*,BufferedSocket*> SocketCull;
-
/** Globally accessible fake user record. This is used to force mode changes etc across s2s, etc.. bit ugly, but.. better than how this was done in 1.1
* Reason for it:
* kludge alert!
@@ -527,13 +520,6 @@ class CoreExport InspIRCd : public classbase
*/
time_t Time();
- /** Process a user whos socket has been flagged as active
- * @param cu The user to process
- * @return There is no actual return value, however upon exit, the user 'cu' may have been
- * marked for deletion in the global CullList.
- */
- caller1<void, User*> ProcessUser;
-
/** Bind all ports specified in the configuration file.
* @return The number of ports bound without error
*/
@@ -924,11 +910,6 @@ class CoreExport InspIRCd : public classbase
*/
int Run();
- /** Force all BufferedSockets to be removed which are due to
- * be culled.
- */
- void BufferedSocketCull();
-
/** Adds an extban char to the 005 token.
*/
void AddExtBanChar(char c);
diff --git a/include/inspsocket.h b/include/inspsocket.h
index 32f2dab1a..73aa748a0 100644
--- a/include/inspsocket.h
+++ b/include/inspsocket.h
@@ -36,6 +36,10 @@ enum BufferedSocketState
*/
enum BufferedSocketError
{
+ /** No error */
+ I_ERR_NONE,
+ /** Socket was closed by peer */
+ I_ERR_DISCONNECT,
/** Socket connect timed out */
I_ERR_TIMEOUT,
/** Socket could not be created */
@@ -44,17 +48,16 @@ enum BufferedSocketError
I_ERR_CONNECT,
/** Socket could not bind to local port/ip */
I_ERR_BIND,
- /** Socket could not reslve host (depreciated) */
- I_ERR_RESOLVE,
/** Socket could not write data */
I_ERR_WRITE,
/** No more file descriptors left to create socket! */
- I_ERR_NOMOREFDS
+ I_ERR_NOMOREFDS,
+ /** Some other error */
+ I_ERR_OTHER
};
/* Required forward declarations */
class BufferedSocket;
-class InspIRCd;
/** Used to time out socket connections
*/
@@ -65,10 +68,6 @@ class CoreExport SocketTimeout : public Timer
*/
BufferedSocket* sock;
- /** Server instance creating the timeout class
- */
- InspIRCd* ServerInstance;
-
/** File descriptor of class this is attached to
*/
int sfd;
@@ -81,7 +80,7 @@ class CoreExport SocketTimeout : public Timer
* @param secs_from_now Seconds from now to time out
* @param now The current time
*/
- SocketTimeout(int fd, InspIRCd* Instance, BufferedSocket* thesock, long secs_from_now, time_t now) : Timer(secs_from_now, now), sock(thesock), ServerInstance(Instance), sfd(fd) { };
+ SocketTimeout(int fd, BufferedSocket* thesock, long secs_from_now, time_t now) : Timer(secs_from_now, now), sock(thesock), sfd(fd) { }
/** Handle tick event
*/
@@ -89,6 +88,67 @@ class CoreExport SocketTimeout : public Timer
};
/**
+ * StreamSocket is a class that wraps a TCP socket and handles send
+ * and receive queues, including passing them to IO hooks
+ */
+class CoreExport StreamSocket : public EventHandler
+{
+ /** Module that handles raw I/O for this socket, or NULL */
+ Module *IOHook;
+ /** Private send queue. Note that individual strings may be shared
+ */
+ std::deque<std::string> sendq;
+ /** Length, in bytes, of the sendq */
+ size_t sendq_len;
+ /** Error - if nonempty, the socket is dead, and this is the reason. */
+ std::string error;
+ protected:
+ std::string recvq;
+ public:
+ StreamSocket() : IOHook(NULL), sendq_len(0) {}
+ inline Module* GetIOHook() { return IOHook; }
+ inline void AddIOHook(Module* m) { IOHook = m; }
+ inline void DelIOHook() { IOHook = NULL; }
+ /** Handle event from socket engine.
+ * This will call OnDataReady if there is *new* data in recvq
+ */
+ virtual void HandleEvent(EventType et, int errornum = 0);
+ /** Dispatched from HandleEvent */
+ virtual void DoRead();
+ /** Dispatched from HandleEvent */
+ virtual void DoWrite();
+
+ /** Sets the error message for this socket. Once set, the socket is dead. */
+ void SetError(const std::string& err) { if (error.empty()) error = err; }
+
+ /** Gets the error message for this socket. */
+ const std::string& getError() const { return error; }
+
+ /** Called when new data is present in recvq */
+ virtual void OnDataReady() = 0;
+ /** Called when the socket gets an error from socket engine or IO hook */
+ virtual void OnError(BufferedSocketError e) = 0;
+
+ /** Send the given data out the socket, either now or when writes unblock
+ */
+ void WriteData(const std::string& data);
+ /** Convenience function: read a line from the socket
+ * @param line The line read
+ * @param delim The line delimiter
+ * @return true if a line was read
+ */
+ bool GetNextLine(std::string& line, char delim = '\n');
+ /** Useful for implementing sendq exceeded */
+ inline const size_t getSendQSize() const { return sendq_len; }
+
+ /**
+ * Close the socket, remove from socket engine, etc
+ */
+ virtual void Close();
+ /** This ensures that close is called prior to destructor */
+ virtual void cull();
+};
+/**
* BufferedSocket is an extendable socket class which modules
* can use for TCP socket support. It is fully integrated
* into InspIRCds socket loop and attaches its sockets to
@@ -97,34 +157,13 @@ class CoreExport SocketTimeout : public Timer
*
* To use BufferedSocket, you must inherit a class from it.
*/
-class CoreExport BufferedSocket : public EventHandler
+class CoreExport BufferedSocket : public StreamSocket
{
public:
-
- /** Bind IP
- */
- std::string cbindip;
-
- /** Instance we were created by
- */
- InspIRCd* ServerInstance;
-
- /** Timeout class or NULL
+ /** Timeout object or NULL
*/
SocketTimeout* Timeout;
- /** Socket output buffer (binary safe)
- */
- std::deque<std::string> outbuffer;
-
- /** The hostname connected to
- */
- char host[MAXBUF];
-
- /** The port connected to
- */
- int port;
-
/**
* The state for this socket, either
* listening, connecting, connected
@@ -132,220 +171,52 @@ class CoreExport BufferedSocket : public EventHandler
*/
BufferedSocketState state;
- /**
- * The IP address being connected
- * to stored in string form for
- * easy retrieval by accessors.
- */
- char IP[MAXBUF];
-
- /**
- * Used by accept() to indicate the
- * sizes of the sockaddr_in structures
- */
- socklen_t length;
-
- /** Flushes the write buffer
- * @returns true if the writing failed, false if it was successful
- */
- bool FlushWriteBuffer();
-
- /** Set the queue sizes
- * This private method sets the operating system queue
- * sizes for this socket to 65535 so that it can queue
- * more information without application-level queueing
- * which was required in older software.
- */
- void SetQueues();
-
- /** When the socket has been marked as closing, this flag
- * will be set to true, then the next time the socket is
- * examined, the socket is deleted and closed.
- */
- bool ClosePending;
-
- /**
- * Bind to an address
- * @param ip IP to bind to
- * @return True is the binding succeeded
- */
- bool BindAddr(const std::string &ip);
-
- /** (really) Try bind to a given IP setup. For internal use only.
- */
- bool DoBindMagic(const std::string &current_ip);
-
- /**
- * The default constructor does nothing
- * and should not be used.
- */
- BufferedSocket(InspIRCd* SI);
-
+ BufferedSocket();
/**
* This constructor is used to associate
* an existing connecting with an BufferedSocket
* class. The given file descriptor must be
* valid, and when initialized, the BufferedSocket
- * will be set with the given IP address
- * and placed in CONNECTED state.
- */
- BufferedSocket(InspIRCd* SI, int newfd, const char* ip);
-
- /**
- * This constructor is used to create a new outbound connection to another host.
- * Note that if you specify a hostname in the 'ipaddr' parameter, this class will not
- * connect. You must resolve your hostnames before passing them to BufferedSocket. To do so,
- * you should use the nonblocking class 'Resolver'.
- * @param ipaddr The IP to connect to, or bind to
- * @param port The port number to connect to
- * @param maxtime Number of seconds to wait, if connecting, before the connection times out and an OnTimeout() event is generated
- * @param connectbindip When creating an outbound connection, the IP to bind the connection to. If not defined, the port is not bound.
- * @return On exit, GetState() returns I_ERROR if an error occured, and errno can be used to read the socket error.
- */
- BufferedSocket(InspIRCd* SI, const std::string &ipaddr, int port, unsigned long maxtime, const std::string &connectbindip = "");
-
- /**
- * This method is called when an outbound
- * connection on your socket is completed.
- * @return false to abort the connection, true to continue
- */
- virtual bool OnConnected();
-
- /**
- * This method is called when an error occurs.
- * A closed socket in itself is not an error,
- * however errors also generate close events.
- * @param e The error type which occured
+ * will be placed in CONNECTED state.
*/
- virtual void OnError(BufferedSocketError e);
+ BufferedSocket(int newfd);
- /**
- * When an established connection is terminated,
- * the OnDisconnect method is triggered.
+ /** Begin connection to the given address
+ * This will create a socket, register with socket engine, and start the asynchronous
+ * connection process. If an error is detected at this point (such as out of file descriptors),
+ * OnError will be called; otherwise, the state will become CONNECTING.
+ * @param dest Address to connect to
+ * @param bind Address to bind to (if NULL, no bind will be done)
+ * @param timeout Time to wait for connection
*/
- virtual int OnDisconnect();
+ void DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
- /**
- * When there is data waiting to be read on a
- * socket, the OnDataReady() method is called.
- * Within this method, you *MUST* call the Read()
- * method to read any pending data. At its lowest
- * level, this event is signalled by the core via
- * the socket engine. If you return false from this
- * function, the core removes your socket from its
- * list and erases it from the socket engine, then
- * calls BufferedSocket::Close() and deletes it.
- * @return false to close the socket
+ /** This method is called when an outbound connection on your socket is
+ * completed.
*/
- virtual bool OnDataReady();
+ virtual void OnConnected();
- /**
- * When it is ok to write to the socket, and a
- * write event was requested, this method is
- * triggered.
- *
- * Within this method you should call
- * write() or send() etc, to send data to the
- * other end of the socket.
- *
- * Further write events will not be triggered
- * unless you call SocketEngine::WantWrite().
- *
- * The default behaviour of this method is to
- * flush the write buffer, respecting the IO
- * hooking modules.
- *
- * XXX: this used to be virtual, ask us if you need it to be so.
- * @return false to close the socket
+ /** When there is data waiting to be read on a socket, the OnDataReady()
+ * method is called.
*/
- bool OnWriteReady();
+ virtual void OnDataReady() = 0;
/**
- * When an outbound connection fails, and the
- * attempt times out, you will receive this event.
- * The method will trigger once maxtime seconds are
- * reached (as given in the constructor) just
- * before the socket's descriptor is closed.
- * A failed DNS lookup may cause this event if
- * the DNS server is not responding, as well as
- * a failed connect() call, because DNS lookups are
- * nonblocking as implemented by this class.
+ * When an outbound connection fails, and the attempt times out, you
+ * will receive this event. The method will trigger once maxtime
+ * seconds are reached (as given in the constructor) just before the
+ * socket's descriptor is closed. A failed DNS lookup may cause this
+ * event if the DNS server is not responding, as well as a failed
+ * connect() call, because DNS lookups are nonblocking as implemented by
+ * this class.
*/
virtual void OnTimeout();
- /**
- * Whenever close() is called, OnClose() will be
- * called first. Please note that this means
- * OnClose will be called alongside OnError(),
- * OnTimeout(), and Close().
- */
- virtual void OnClose();
-
- /**
- * Reads all pending bytes from the socket
- * into a char* array which can be up to
- * 16 kilobytes in length.
- */
- virtual const char* Read();
-
- /**
- * Returns the IP address associated with
- * this connection, or an empty string if
- * no IP address exists.
- */
- std::string GetIP();
-
- /**
- * Writes a std::string to the socket. No carriage
- * returns or linefeeds are appended to the string.
- * @param data The data to send
- */
- virtual void Write(const std::string &data);
-
- /**
- * Changes the socket's state. The core uses this
- * to change socket states, and you should not call
- * it directly.
- */
- void SetState(BufferedSocketState s);
-
- /**
- * Returns the current socket state.
- */
- BufferedSocketState GetState();
-
- /** Mark a socket as being connected and call appropriate events.
- */
- bool InternalMarkConnected();
-
- /**
- * This method causes the socket to close, and may
- * also be triggered by other methods such as OnTimeout
- * and OnError.
- */
- virtual void Close();
-
- /**
- * The destructor may implicitly call OnClose(), and
- * will close() and shutdown() the file descriptor
- * used for this socket.
- */
virtual ~BufferedSocket();
-
- /**
- * This method attempts to connect to a hostname.
- * This method is asyncronous.
- * @param maxtime Number of seconds to wait, if connecting, before the connection times out and an OnTimeout() event is generated
- */
- virtual bool DoConnect(unsigned long maxtime);
-
- /** Handle event from EventHandler parent class
- */
- void HandleEvent(EventType et, int errornum = 0);
-
- /** Returns true if this socket is readable
- */
- bool Readable();
+ protected:
+ virtual void DoWrite();
+ BufferedSocketError BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned long timeout);
+ BufferedSocketError BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip);
};
#endif
diff --git a/include/modules.h b/include/modules.h
index f40cd49fd..982d83754 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -406,10 +406,9 @@ enum Implementation
I_OnRawMode, I_OnCheckKey, I_OnCheckLimit, I_OnCheckBan, I_OnCheckChannelBan, I_OnExtBanCheck,
I_OnStats, I_OnChangeLocalUserHost, I_OnChangeLocalUserGecos, I_OnPreTopicChange,
I_OnPostTopicChange, I_OnEvent, I_OnRequest, I_OnGlobalOper, I_OnPostConnect, I_OnAddBan,
- I_OnDelBan, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketWrite, I_OnRawSocketRead,
- I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
+ I_OnDelBan, I_OnChangeLocalUserGECOS, I_OnUserRegister, I_OnChannelPreDelete, I_OnChannelDelete,
I_OnPostOper, I_OnSyncNetwork, I_OnSetAway, I_OnUserList, I_OnPostCommand, I_OnPostJoin,
- I_OnWhoisLine, I_OnBuildExemptList, I_OnRawSocketConnect, I_OnGarbageCollect, I_OnBufferFlushed,
+ I_OnWhoisLine, I_OnBuildExemptList, I_OnGarbageCollect, I_OnBufferFlushed,
I_OnText, I_OnPassCompare, I_OnRunTestSuite, I_OnNamesListItem, I_OnNumeric, I_OnHookIO,
I_OnHostCycle, I_OnPreRehash, I_OnModuleRehash, I_OnSendWhoLine, I_OnChangeIdent,
I_END
@@ -1242,9 +1241,9 @@ class CoreExport Module : public Extensible
* @param user The item to possibly install the I/O hook on
* @param via The port that <user> connected on
*/
- virtual void OnHookIO(EventHandler* user, ListenSocketBase* via);
+ virtual void OnHookIO(StreamSocket*, ListenSocketBase* via);
- /** Called immediately after any connection is accepted. This is intended for raw socket
+ /** Called immediately after any connection is accepted. This is intended for raw socket
* processing (e.g. modules which wrap the tcp connection within another library) and provides
* no information relating to a user record as the connection has not been assigned yet.
* There are no return values from this call as all modules get an opportunity if required to
@@ -1254,48 +1253,38 @@ class CoreExport Module : public Extensible
* @param server The server IP address and port
* @param localport The local port number the user connected to
*/
- virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
+ virtual void OnStreamSocketAccept(StreamSocket*, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server);
- /** Called immediately before any write() operation on a user's socket in the core. Because
- * this event is a low level event no user information is associated with it. It is intended
- * for use by modules which may wrap connections within another API such as SSL for example.
- * return a non-zero result if you have handled the write operation, in which case the core
- * will not call write().
- * @param fd The file descriptor of the socket
- * @param buffer A char* buffer being written
- * @param Number of characters to write
- * @return Number of characters actually written or 0 if you didn't handle the operation
+ /**
+ * Called when a hooked stream has data to write, or when the socket
+ * engine returns it as writable
+ * @param socket The socket in question
+ * @param sendq Data to send to the socket
+ * @return 1 if the sendq has been completely emptied, 0 if there is
+ * still data to send, and -1 if there was an error
*/
- virtual int OnRawSocketWrite(int fd, const char* buffer, int count);
+ virtual int OnStreamSocketWrite(StreamSocket*, std::string& sendq);
/** Called immediately before any socket is closed. When this event is called, shutdown()
* has not yet been called on the socket.
* @param fd The file descriptor of the socket prior to close()
*/
- virtual void OnRawSocketClose(int fd);
+ virtual void OnStreamSocketClose(StreamSocket*);
/** Called immediately upon connection of an outbound BufferedSocket which has been hooked
* by a module.
* @param fd The file descriptor of the socket immediately after connect()
*/
- virtual void OnRawSocketConnect(int fd);
-
- /** Called immediately before any read() operation on a client socket in the core.
- * This occurs AFTER the select() or poll() so there is always data waiting to be read
- * when this event occurs.
- * Your event should return 1 if it has handled the reading itself, which prevents the core
- * just using read(). You should place any data read into buffer, up to but NOT GREATER THAN
- * the value of count. The value of readresult must be identical to an actual result that might
- * be returned from the read() system call, for example, number of bytes read upon success,
- * 0 upon EOF or closed socket, and -1 for error. If your function returns a nonzero value,
- * you MUST set readresult.
- * @param fd The file descriptor of the socket
- * @param buffer A char* buffer being read to
- * @param count The size of the buffer
- * @param readresult The amount of characters read, or 0
- * @return nonzero if the event was handled, in which case readresult must be valid on exit
- */
- virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult);
+ virtual void OnStreamSocketConnect(StreamSocket*);
+
+ /**
+ * Called when the stream socket has data to read
+ * @param socket The socket that is ready
+ * @param recvq The receive queue that new data should be appended to
+ * @return 1 if new data has been read, 0 if no new data is ready (but the
+ * socket is still connected), -1 if there was an error or close
+ */
+ virtual int OnStreamSocketRead(StreamSocket*, std::string& recvq);
/** Called whenever a user sets away or returns from being away.
* The away message is available as a parameter, but should not be modified.
diff --git a/include/socket.h b/include/socket.h
index 5ca9fc18f..af3eccea2 100644
--- a/include/socket.h
+++ b/include/socket.h
@@ -99,7 +99,7 @@ namespace irc
CoreExport int OpenTCPSocket(const char* addr, int socktype = SOCK_STREAM);
/** Return the size of the structure for syscall passing */
- CoreExport int sa_size(irc::sockets::sockaddrs& sa);
+ CoreExport int sa_size(const irc::sockets::sockaddrs& sa);
/** Convert an address-port pair into a binary sockaddr
* @param addr The IP address, IPv4 or IPv6
diff --git a/include/socketengine.h b/include/socketengine.h
index a191ff12d..4e87f7494 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -69,32 +69,11 @@ class CoreExport EventHandler : public Extensible
* other forms of IPC.
*/
int fd;
-
- /** Pointer to the module which has hooked the given EventHandler for IO events.
- */
- Module *IOHook;
public:
-
- /** Return the current hooker of IO events for this socket, or NULL.
- * @return Hooker module, if set, or NULL.
- */
- Module *GetIOHook();
-
- /** Set a module as hooking IO events on this socket.
- * @param IOHooker The module hooking IO
- * @return True if the hook could be added, false otherwise.
- */
- bool AddIOHook(Module *IOHooker);
-
- /** Remove IO hooking from a module
- * @return True if hooking was successfully removed, false otherwise.
- */
- bool DelIOHook();
-
/** Get the current file descriptor
* @return The file descriptor of this handler
*/
- int GetFd();
+ inline int GetFd() const { return fd; }
/** Set a new file desciptor
* @param FD The new file descriptor. Do not
@@ -112,44 +91,10 @@ class CoreExport EventHandler : public Extensible
*/
virtual ~EventHandler() {}
- /** Override this function to indicate readability.
- * @return This should return true if the function
- * wishes to receive EVENT_READ events. Do not change
- * what this function returns while the event handler
- * is still added to a SocketEngine instance!
- * If this function is unimplemented, the base class
- * will return true.
- *
- * NOTE: You cannot set both Readable() and
- * Writeable() to true. If you wish to receive
- * a write event for your object, you must call
- * SocketEngine::WantWrite() instead. This will
- * trigger your objects next EVENT_WRITE type event.
- */
- virtual bool Readable();
-
- /** Override this function to indicate writeability.
- * @return This should return true if the function
- * wishes to receive EVENT_WRITE events. Do not change
- * what this function returns while the event handler
- * is still added to a SocketEngine instance!
- * If this function is unimplemented, the base class
- * will return false.
- *
- * NOTE: You cannot set both Readable() and
- * Writeable() to true. If you wish to receive
- * a write event for your object, you must call
- * SocketEngine::WantWrite() instead. This will
- * trigger your objects next EVENT_WRITE type event.
- */
- virtual bool Writeable();
-
/** Process an I/O event.
* You MUST implement this function in your derived
* class, and it will be called whenever read or write
- * events are received, depending on what your functions
- * Readable() and Writeable() returns and wether you
- * previously made a call to SocketEngine::WantWrite().
+ * events are received.
* @param et either one of EVENT_READ for read events,
* and EVENT_WRITE for write events.
*/
@@ -177,9 +122,6 @@ class CoreExport EventHandler : public Extensible
class CoreExport SocketEngine
{
protected:
- /** Owner/Creator
- */
- InspIRCd* ServerInstance;
/** Handle to socket engine, where needed.
*/
int EngineHandle;
@@ -211,9 +153,8 @@ public:
* failure (for example, you try and enable
* epoll on a 2.4 linux kernel) then this
* function may bail back to the shell.
- * @param Instance The creator/owner of this object
*/
- SocketEngine(InspIRCd* Instance);
+ SocketEngine();
/** Destructor.
* The destructor transparently tidies up
@@ -221,15 +162,14 @@ public:
*/
virtual ~SocketEngine();
- /** Add an EventHandler object to the engine.
- * Use AddFd to add a file descriptor to the
- * engine and have the socket engine monitor
- * it. You must provide an object derived from
- * EventHandler which implements HandleEvent()
- * and optionally Readable() and Writeable().
+ /** Add an EventHandler object to the engine. Use AddFd to add a file
+ * descriptor to the engine and have the socket engine monitor it. You
+ * must provide an object derived from EventHandler which implements
+ * HandleEvent().
* @param eh An event handling object to add
+ * @param writeFirst Wait for a write event instead of a read
*/
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false) = 0;
/** If you call this function and pass it an
* event handler, that event handler will
@@ -242,7 +182,7 @@ public:
* @param eh An event handler which wants to
* receive the next writeability event.
*/
- virtual void WantWrite(EventHandler* eh);
+ virtual void WantWrite(EventHandler* eh) = 0;
/** Returns the maximum number of file descriptors
* you may store in the socket engine at any one time.
@@ -273,7 +213,7 @@ public:
* @param force *DANGEROUS* See method description!
* @return True if the event handler was removed
*/
- virtual bool DelFd(EventHandler* eh, bool force = false);
+ virtual bool DelFd(EventHandler* eh, bool force = false) = 0;
/** Returns true if a file descriptor exists in
* the socket engine's list.
@@ -305,7 +245,7 @@ public:
* in /VERSION responses.
* @return The socket engine name
*/
- virtual std::string GetName();
+ virtual std::string GetName() = 0;
/** Returns true if the file descriptors in the
* given event handler are within sensible ranges
diff --git a/include/socketengines/socketengine_epoll.h b/include/socketengines/socketengine_epoll.h
index 6e6818212..3e08179ae 100644
--- a/include/socketengines/socketengine_epoll.h
+++ b/include/socketengines/socketengine_epoll.h
@@ -23,8 +23,6 @@
#include <sys/epoll.h>
#define EP_DELAY 5
-class InspIRCd;
-
/** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll().
*/
class EPollEngine : public SocketEngine
@@ -35,13 +33,12 @@ private:
struct epoll_event* events;
public:
/** Create a new EPollEngine
- * @param Instance The creator of this object
*/
- EPollEngine(InspIRCd* Instance);
+ EPollEngine();
/** Delete an EPollEngine
*/
virtual ~EPollEngine();
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
@@ -57,7 +54,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on EpollEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new EPollEngine(Instance); }
+ SocketEngine* Create() { return new EPollEngine; }
};
#endif
diff --git a/include/socketengines/socketengine_iocp.h b/include/socketengines/socketengine_iocp.h
index 302fdbd2c..dd34227d3 100644
--- a/include/socketengines/socketengine_iocp.h
+++ b/include/socketengines/socketengine_iocp.h
@@ -121,7 +121,7 @@ public:
/** Creates an IOCP Socket Engine
* @param Instance The creator of this object
*/
- IOCPEngine(InspIRCd* Instance);
+ IOCPEngine();
/** Deletes an IOCP socket engine and all the attached sockets
*/
@@ -131,7 +131,7 @@ public:
* @param eh EventHandler to add
* @return True if success, false if no room
*/
- bool AddFd(EventHandler* eh);
+ bool AddFd(EventHandler* eh, bool writeFirst = false);
/** Gets the maximum number of file descriptors that this engine can handle.
* @return The number of file descriptors
@@ -234,7 +234,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on IOCPEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new IOCPEngine(Instance); }
+ SocketEngine* Create() { return new IOCPEngine; }
};
#endif
diff --git a/include/socketengines/socketengine_kqueue.h b/include/socketengines/socketengine_kqueue.h
index 41459f561..a09e93553 100644
--- a/include/socketengines/socketengine_kqueue.h
+++ b/include/socketengines/socketengine_kqueue.h
@@ -24,8 +24,6 @@
#include <sys/time.h>
#include "socketengine.h"
-class InspIRCd;
-
/** A specialisation of the SocketEngine class, designed to use FreeBSD kqueue().
*/
class KQueueEngine : public SocketEngine
@@ -39,13 +37,12 @@ private:
struct timespec ts;
public:
/** Create a new KQueueEngine
- * @param Instance The creator of this object
*/
- KQueueEngine(InspIRCd* Instance);
+ KQueueEngine();
/** Delete a KQueueEngine
*/
virtual ~KQueueEngine();
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
@@ -62,7 +59,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on KQueueEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new KQueueEngine(Instance); }
+ SocketEngine* Create() { return new KQueueEngine; }
};
#endif
diff --git a/include/socketengines/socketengine_poll.h b/include/socketengines/socketengine_poll.h
index df1100d09..725ad225c 100644
--- a/include/socketengines/socketengine_poll.h
+++ b/include/socketengines/socketengine_poll.h
@@ -48,13 +48,12 @@ private:
std::map<int, unsigned int> fd_mappings;
public:
/** Create a new PollEngine
- * @param Instance The creator of this object
*/
- PollEngine(InspIRCd* Instance);
+ PollEngine();
/** Delete a PollEngine
*/
virtual ~PollEngine();
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false);
virtual EventHandler* GetRef(int fd);
virtual int GetMaxFds();
virtual int GetRemainingFds();
@@ -71,7 +70,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on PollEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new PollEngine(Instance); }
+ SocketEngine* Create() { return new PollEngine; }
};
#endif
diff --git a/include/socketengines/socketengine_ports.h b/include/socketengines/socketengine_ports.h
index 40d5da51a..03df456f2 100644
--- a/include/socketengines/socketengine_ports.h
+++ b/include/socketengines/socketengine_ports.h
@@ -26,8 +26,6 @@
#include "socketengine.h"
#include <port.h>
-class InspIRCd;
-
/** A specialisation of the SocketEngine class, designed to use solaris 10 I/O completion ports
*/
class PortsEngine : public SocketEngine
@@ -40,11 +38,11 @@ public:
/** Create a new PortsEngine
* @param Instance The creator of this object
*/
- PortsEngine(InspIRCd* Instance);
+ PortsEngine();
/** Delete a PortsEngine
*/
virtual ~PortsEngine();
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
@@ -60,7 +58,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on PortsEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new PortsEngine(Instance); }
+ SocketEngine* Create() { return new PortsEngine; }
};
#endif
diff --git a/include/socketengines/socketengine_select.h b/include/socketengines/socketengine_select.h
index a248e8a8e..a1993f19f 100644
--- a/include/socketengines/socketengine_select.h
+++ b/include/socketengines/socketengine_select.h
@@ -24,8 +24,6 @@
#include "inspircd.h"
#include "socketengine.h"
-class InspIRCd;
-
/** A specialisation of the SocketEngine class, designed to use traditional select().
*/
class SelectEngine : public SocketEngine
@@ -45,11 +43,11 @@ public:
/** Create a new SelectEngine
* @param Instance The creator of this object
*/
- SelectEngine(InspIRCd* Instance);
+ SelectEngine();
/** Delete a SelectEngine
*/
virtual ~SelectEngine();
- virtual bool AddFd(EventHandler* eh);
+ virtual bool AddFd(EventHandler* eh, bool writeFirst = false);
virtual int GetMaxFds();
virtual int GetRemainingFds();
virtual bool DelFd(EventHandler* eh, bool force = false);
@@ -65,7 +63,7 @@ class SocketEngineFactory
public:
/** Create a new instance of SocketEngine based on SelectEngine
*/
- SocketEngine* Create(InspIRCd* Instance) { return new SelectEngine(Instance); }
+ SocketEngine* Create() { return new SelectEngine; }
};
#endif
diff --git a/include/users.h b/include/users.h
index f9be74924..7ec35535f 100644
--- a/include/users.h
+++ b/include/users.h
@@ -15,6 +15,7 @@
#define __USERS_H__
#include "socket.h"
+#include "inspsocket.h"
#include "dns.h"
#include "mode.h"
@@ -210,7 +211,7 @@ class User;
* 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 EventHandler
+class CoreExport User : public StreamSocket
{
private:
/** A list of channels the user has a pending invite to.
@@ -405,17 +406,6 @@ class CoreExport User : public EventHandler
*/
std::string password;
- /** User's receive queue.
- * Lines from the IRCd awaiting processing are stored here.
- * Upgraded april 2005, old system a bit hairy.
- */
- std::string recvq;
-
- /** User's send queue.
- * Lines waiting to be sent are stored here until their buffer is flushed.
- */
- std::string sendq;
-
/** Whether or not to send an snotice about this user's quitting
*/
bool quietquit;
@@ -596,44 +586,6 @@ class CoreExport User : public EventHandler
*/
bool HasModePermission(unsigned char mode, ModeType type);
- /** Calls read() to read some data for this user using their fd.
- * @param buffer The buffer to read into
- * @param size The size of data to read
- * @return The number of bytes read, or -1 if an error occured.
- */
- int ReadData(void* buffer, size_t size);
-
- /** This method adds data to the read buffer of the user.
- * The buffer can grow to any size within limits of the available memory,
- * managed by the size of a std::string, however if any individual line in
- * the buffer grows over 600 bytes in length (which is 88 chars over the
- * RFC-specified limit per line) then the method will return false and the
- * text will not be inserted.
- * @param a The string to add to the users read buffer
- * @return True if the string was successfully added to the read buffer
- */
- bool AddBuffer(const std::string &a);
-
- /** This method returns true if the buffer contains at least one carriage return
- * character (e.g. one complete line may be read)
- * @return True if there is at least one complete line in the users buffer
- */
- bool BufferIsReady();
-
- /** This function clears the entire buffer by setting it to an empty string.
- */
- void ClearBuffer();
-
- /** This method returns the first available string at the tail end of the buffer
- * and advances the tail end of the buffer past the string. This means it is
- * a one way operation in a similar way to strtok(), and multiple calls return
- * multiple lines if they are available. The results of this function if there
- * are no lines to be read are unknown, always use BufferIsReady() to check if
- * it is ok to read the buffer before calling GetBuffer().
- * @return The string at the tail end of this users buffer
- */
- std::string GetBuffer();
-
/** 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.
@@ -641,14 +593,6 @@ class CoreExport User : public EventHandler
*/
void AddWriteBuf(const std::string &data);
- /** Flushes as much of the user's buffer to the file descriptor as possible.
- * This function may not always flush the entire buffer, rather instead as much of it
- * as it possibly can. If the send() call fails to send the entire buffer, the buffer
- * position is advanced forwards and the rest of the data sent at the next call to
- * this method.
- */
- void FlushWriteBuf();
-
/** 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
*/
@@ -672,12 +616,6 @@ class CoreExport User : public EventHandler
*/
const std::string& MakeHostIP();
- /** Shuts down and closes the user's socket
- * This will not cause the user to be deleted. Use InspIRCd::QuitUser for this,
- * which will call CloseSocket() for you.
- */
- void CloseSocket();
-
/** Add the user to WHOWAS system
*/
void AddToWhoWas();
@@ -911,16 +849,13 @@ class CoreExport User : public EventHandler
*/
void DecreasePenalty(int decrease);
- /** Handle socket event.
- * From EventHandler class.
- * @param et Event type
- * @param errornum Error number for EVENT_ERROR events
- */
- void HandleEvent(EventType et, int errornum = 0);
+ void OnDataReady();
+ void OnError(BufferedSocketError error);
/** Default destructor
*/
virtual ~User();
+ virtual void cull();
};
/** Derived from Resolver, and performs user forward/reverse lookups.