summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--src/base.cpp8
-rw-r--r--src/command_parse.cpp36
-rw-r--r--src/cull_list.cpp8
-rw-r--r--src/helperfuncs.cpp12
-rw-r--r--src/inspircd.cpp23
-rw-r--r--src/inspsocket.cpp567
-rw-r--r--src/modules.cpp12
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp227
-rw-r--r--src/modules/extra/m_ssl_openssl.cpp182
-rw-r--r--src/modules/extra/m_ziplink.cpp111
-rw-r--r--src/modules/m_httpd.cpp45
-rw-r--r--src/modules/m_spanningtree/addline.cpp10
-rw-r--r--src/modules/m_spanningtree/admin.cpp14
-rw-r--r--src/modules/m_spanningtree/away.cpp2
-rw-r--r--src/modules/m_spanningtree/capab.cpp14
-rw-r--r--src/modules/m_spanningtree/compat.cpp2
-rw-r--r--src/modules/m_spanningtree/delline.cpp2
-rw-r--r--src/modules/m_spanningtree/encap.cpp2
-rw-r--r--src/modules/m_spanningtree/fhost.cpp2
-rw-r--r--src/modules/m_spanningtree/fident.cpp2
-rw-r--r--src/modules/m_spanningtree/fjoin.cpp8
-rw-r--r--src/modules/m_spanningtree/fmode.cpp6
-rw-r--r--src/modules/m_spanningtree/fname.cpp2
-rw-r--r--src/modules/m_spanningtree/ftopic.cpp4
-rw-r--r--src/modules/m_spanningtree/handshaketimer.cpp6
-rw-r--r--src/modules/m_spanningtree/hmac.cpp4
-rw-r--r--src/modules/m_spanningtree/kill.cpp4
-rw-r--r--src/modules/m_spanningtree/main.cpp5
-rw-r--r--src/modules/m_spanningtree/metadata.cpp10
-rw-r--r--src/modules/m_spanningtree/modules.cpp4
-rw-r--r--src/modules/m_spanningtree/motd.cpp14
-rw-r--r--src/modules/m_spanningtree/netburst.cpp32
-rw-r--r--src/modules/m_spanningtree/nickcollide.cpp2
-rw-r--r--src/modules/m_spanningtree/operquit.cpp2
-rw-r--r--src/modules/m_spanningtree/opertype.cpp8
-rw-r--r--src/modules/m_spanningtree/override_stats.cpp4
-rw-r--r--src/modules/m_spanningtree/ping.cpp4
-rw-r--r--src/modules/m_spanningtree/pong.cpp2
-rw-r--r--src/modules/m_spanningtree/push.cpp2
-rw-r--r--src/modules/m_spanningtree/resolvers.cpp5
-rw-r--r--src/modules/m_spanningtree/save.cpp4
-rw-r--r--src/modules/m_spanningtree/server.cpp46
-rw-r--r--src/modules/m_spanningtree/stats.cpp8
-rw-r--r--src/modules/m_spanningtree/svsjoin.cpp4
-rw-r--r--src/modules/m_spanningtree/svsnick.cpp4
-rw-r--r--src/modules/m_spanningtree/svspart.cpp4
-rw-r--r--src/modules/m_spanningtree/time.cpp10
-rw-r--r--src/modules/m_spanningtree/treesocket.h31
-rw-r--r--src/modules/m_spanningtree/treesocket1.cpp128
-rw-r--r--src/modules/m_spanningtree/treesocket2.cpp32
-rw-r--r--src/modules/m_spanningtree/uid.cpp14
-rw-r--r--src/modules/m_spanningtree/utils.cpp29
-rw-r--r--src/modules/m_spanningtree/utils.h3
-rw-r--r--src/modules/m_spanningtree/whois.cpp6
-rw-r--r--src/socket.cpp2
-rw-r--r--src/socketengine.cpp61
-rw-r--r--src/socketengines/socketengine_epoll.cpp7
-rw-r--r--src/socketengines/socketengine_iocp.cpp6
-rw-r--r--src/socketengines/socketengine_kqueue.cpp6
-rw-r--r--src/socketengines/socketengine_poll.cpp10
-rw-r--r--src/socketengines/socketengine_ports.cpp6
-rw-r--r--src/socketengines/socketengine_select.cpp15
-rw-r--r--src/stats.cpp4
-rw-r--r--src/threadengines/threadengine_pthread.cpp33
-rw-r--r--src/threadengines/threadengine_win32.cpp17
-rw-r--r--src/usermanager.cpp27
-rw-r--r--src/userprocess.cpp104
-rw-r--r--src/users.cpp284
82 files changed, 990 insertions, 1950 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.
diff --git a/src/base.cpp b/src/base.cpp
index 27eb4af23..2b022688d 100644
--- a/src/base.cpp
+++ b/src/base.cpp
@@ -26,6 +26,14 @@ classbase::classbase()
{
}
+void classbase::cull()
+{
+}
+
+classbase::~classbase()
+{
+}
+
void BoolSet::Set(int number)
{
this->bits |= bitfields[number];
diff --git a/src/command_parse.cpp b/src/command_parse.cpp
index 92d4b8c24..cbf6a1005 100644
--- a/src/command_parse.cpp
+++ b/src/command_parse.cpp
@@ -226,23 +226,6 @@ CmdResult CommandParser::CallHandler(const std::string &commandname, const std::
return CMD_INVALID;
}
-void CommandParser::DoLines(User* current, bool one_only)
-{
- while (current->BufferIsReady())
- {
- // use GetBuffer to copy single lines into the sanitized string
- std::string single_line = current->GetBuffer();
- current->bytes_in += single_line.length();
- current->cmds_in++;
- if (single_line.length() > MAXBUF - 2) // MAXBUF is 514 to allow for neccessary line terminators
- single_line.resize(MAXBUF - 2); // So to trim to 512 here, we use MAXBUF - 2
-
- // ProcessBuffer returns false if the user has gone over penalty
- if (!ServerInstance->Parser->ProcessBuffer(single_line, current) || one_only)
- break;
- }
-}
-
bool CommandParser::ProcessCommand(User *user, std::string &cmd)
{
std::vector<std::string> command_p;
@@ -435,23 +418,12 @@ void CommandParser::RemoveCommand(Commandtable::iterator safei, Module* source)
bool CommandParser::ProcessBuffer(std::string &buffer,User *user)
{
- std::string::size_type a;
-
- if (!user)
+ if (!user || buffer.empty())
return true;
- while ((a = buffer.rfind("\n")) != std::string::npos)
- buffer.erase(a);
- while ((a = buffer.rfind("\r")) != std::string::npos)
- buffer.erase(a);
-
- if (buffer.length())
- {
- ServerInstance->Logs->Log("USERINPUT", DEBUG,"C[%d] I :%s %s",user->GetFd(), user->nick.c_str(), buffer.c_str());
- return this->ProcessCommand(user,buffer);
- }
-
- return true;
+ ServerInstance->Logs->Log("USERINPUT", DEBUG, "C[%d] I :%s %s",
+ user->GetFd(), user->nick.c_str(), buffer.c_str());
+ return ProcessCommand(user,buffer);
}
bool CommandParser::CreateCommand(Command *f)
diff --git a/src/cull_list.cpp b/src/cull_list.cpp
index 79c077ead..35fa44bfa 100644
--- a/src/cull_list.cpp
+++ b/src/cull_list.cpp
@@ -18,8 +18,12 @@
void CullList::Apply()
{
- for(std::vector<classbase*>::iterator i = list.begin(); i != list.end(); i++)
- delete *i;
+ for(std::set<classbase*>::iterator i = list.begin(); i != list.end(); i++)
+ {
+ classbase* c = *i;
+ c->cull();
+ delete c;
+ }
list.clear();
}
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index 0ec8db966..80feae464 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -125,20 +125,16 @@ void InspIRCd::SendError(const std::string &s)
{
for (std::vector<User*>::const_iterator i = this->Users->local_users.begin(); i != this->Users->local_users.end(); i++)
{
- if ((*i)->registered == REG_ALL)
+ User* u = *i;
+ if (u->registered == REG_ALL)
{
- (*i)->WriteServ("NOTICE %s :%s",(*i)->nick.c_str(),s.c_str());
+ u->WriteServ("NOTICE %s :%s",u->nick.c_str(),s.c_str());
}
else
{
/* Unregistered connections receive ERROR, not a NOTICE */
- (*i)->Write("ERROR :" + s);
+ u->Write("ERROR :" + s);
}
- /* This might generate a whole load of EAGAIN, but we dont really
- * care about this, as if we call SendError something catastrophic
- * has occured anyway, and we wont receive the events for these.
- */
- (*i)->FlushWriteBuf();
}
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 1b23bff02..704fec475 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -110,7 +110,6 @@ void InspIRCd::Cleanup()
{
User* u = *i++;
Users->QuitUser(u, "Server shutdown");
- u->CloseSocket();
}
/* We do this more than once, so that any service providers get a
@@ -323,7 +322,6 @@ InspIRCd::InspIRCd(int argc, char** argv) :
* THIS MUST MATCH ORDER OF DECLARATION OF THE HandleWhateverFunc classes
* within class InspIRCd.
*/
- HandleProcessUser(this),
HandleIsNick(this),
HandleIsIdent(this),
HandleFloodQuitUser(this),
@@ -336,7 +334,6 @@ InspIRCd::InspIRCd(int argc, char** argv) :
* THIS MUST MATCH THE ORDER OF DECLARATION OF THE FUNCTORS, e.g. the methods
* themselves within the class.
*/
- ProcessUser(&HandleProcessUser),
IsChannel(&HandleIsChannel),
IsSID(&HandleIsSID),
Rehash(&HandleRehash),
@@ -387,9 +384,8 @@ InspIRCd::InspIRCd(int argc, char** argv) :
// This must be created first, so other parts of Insp can use it while starting up
this->Logs = new LogManager(this);
- SocketEngineFactory* SEF = new SocketEngineFactory();
- SE = SEF->Create(this);
- delete SEF;
+ SocketEngineFactory SEF;
+ SE = SEF.Create();
this->Threads = new ThreadEngine(this);
@@ -832,9 +828,6 @@ int InspIRCd::Run()
/* if any users were quit, take them out */
this->GlobalCulls.Apply();
- /* If any inspsockets closed, remove them */
- this->BufferedSocketCull();
-
if (this->s_signal)
{
this->SignalHandler(s_signal);
@@ -845,18 +838,6 @@ int InspIRCd::Run()
return 0;
}
-void InspIRCd::BufferedSocketCull()
-{
- for (std::map<BufferedSocket*,BufferedSocket*>::iterator x = SocketCull.begin(); x != SocketCull.end(); ++x)
- {
- this->Logs->Log("MISC",DEBUG,"Cull socket");
- SE->DelFd(x->second);
- x->second->Close();
- delete x->second;
- }
- SocketCull.clear();
-}
-
/**********************************************************************************/
/**
diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp
index 0350858e7..964582062 100644
--- a/src/inspsocket.cpp
+++ b/src/inspsocket.cpp
@@ -16,195 +16,100 @@
#include "inspstring.h"
#include "socketengine.h"
-bool BufferedSocket::Readable()
+BufferedSocket::BufferedSocket()
{
- return (this->state != I_CONNECTING);
+ Timeout = NULL;
+ state = I_ERROR;
}
-BufferedSocket::BufferedSocket(InspIRCd* SI)
+BufferedSocket::BufferedSocket(int newfd)
{
- this->Timeout = NULL;
- this->state = I_DISCONNECTED;
- this->fd = -1;
- this->ServerInstance = SI;
-}
-
-BufferedSocket::BufferedSocket(InspIRCd* SI, int newfd, const char* ip)
-{
- this->Timeout = NULL;
+ Timeout = NULL;
this->fd = newfd;
this->state = I_CONNECTED;
- strlcpy(this->IP,ip,MAXBUF);
- this->ServerInstance = SI;
- if (this->fd > -1)
- this->ServerInstance->SE->AddFd(this);
+ if (fd > -1)
+ ServerInstance->SE->AddFd(this);
}
-BufferedSocket::BufferedSocket(InspIRCd* SI, const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip)
+void BufferedSocket::DoConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip)
{
- this->cbindip = connectbindip;
- this->fd = -1;
- this->ServerInstance = SI;
- strlcpy(host,ipaddr.c_str(),MAXBUF);
- this->Timeout = NULL;
-
- strlcpy(this->host,ipaddr.c_str(),MAXBUF);
- this->port = aport;
-
- irc::sockets::sockaddrs testaddr;
- if (!irc::sockets::aptosa(host, aport, &testaddr))
- {
- this->ServerInstance->Logs->Log("SOCKET", DEBUG,"BUG: Hostname passed to BufferedSocket, rather than an IP address!");
- this->OnError(I_ERR_CONNECT);
- this->Close();
- this->fd = -1;
- this->state = I_ERROR;
- return;
- }
- else
+ BufferedSocketError err = BeginConnect(ipaddr, aport, maxtime, connectbindip);
+ if (err != I_ERR_NONE)
{
- strlcpy(this->IP,host,MAXBUF);
- if (!this->DoConnect(maxtime))
- {
- this->OnError(I_ERR_CONNECT);
- this->Close();
- this->fd = -1;
- this->state = I_ERROR;
- return;
- }
+ state = I_ERROR;
+ SetError(strerror(errno));
+ OnError(err);
}
}
-void BufferedSocket::SetQueues()
+BufferedSocketError BufferedSocket::BeginConnect(const std::string &ipaddr, int aport, unsigned long maxtime, const std::string &connectbindip)
{
- // attempt to increase socket sendq and recvq as high as its possible
- int sendbuf = 32768;
- int recvbuf = 32768;
- if(setsockopt(this->fd,SOL_SOCKET,SO_SNDBUF,(const char *)&sendbuf,sizeof(sendbuf)) || setsockopt(this->fd,SOL_SOCKET,SO_RCVBUF,(const char *)&recvbuf,sizeof(sendbuf)))
+ irc::sockets::sockaddrs addr, bind;
+ if (!irc::sockets::aptosa(ipaddr.c_str(), aport, &addr))
{
- //this->ServerInstance->Log(DEFAULT, "Could not increase SO_SNDBUF/SO_RCVBUF for socket %u", GetFd());
- ; // do nothing. I'm a little sick of people trying to interpret this message as a result of why their incorrect setups don't work.
+ ServerInstance->Logs->Log("SOCKET", DEBUG, "BUG: Hostname passed to BufferedSocket, rather than an IP address!");
+ return I_ERR_CONNECT;
}
-}
-bool BufferedSocket::DoBindMagic(const std::string &current_ip)
-{
- irc::sockets::sockaddrs s;
- if (!irc::sockets::aptosa(current_ip.c_str(), 0, &s))
+ bind.sa.sa_family = 0;
+ if (!connectbindip.empty())
{
- errno = EADDRNOTAVAIL;
- return false;
- }
-
- if (ServerInstance->SE->Bind(this->fd, &s.sa, sa_size(s)) < 0)
- {
- this->state = I_ERROR;
- this->OnError(I_ERR_BIND);
- return false;
+ if (!irc::sockets::aptosa(connectbindip.c_str(), 0, &bind))
+ {
+ return I_ERR_BIND;
+ }
}
- return true;
+ return BeginConnect(addr, bind, maxtime);
}
-/* Most irc servers require you to specify the ip you want to bind to.
- * If you dont specify an IP, they rather dumbly bind to the first IP
- * of the box (e.g. INADDR_ANY). In InspIRCd, we scan thought the IP
- * addresses we've bound server ports to, and we try and bind our outbound
- * connections to the first usable non-loopback and non-any IP we find.
- * This is easier to configure when you have a lot of links and a lot
- * of servers to configure.
- */
-bool BufferedSocket::BindAddr(const std::string &ip_to_bind)
+static void IncreaseOSBuffers(int fd)
{
- ConfigReader Conf(this->ServerInstance);
-
- // Case one: If they provided an IP, try bind it
- if (!ip_to_bind.empty())
- {
- // And if it fails, don't do anything.
- return this->DoBindMagic(ip_to_bind);
- }
-
- for (int j = 0; j < Conf.Enumerate("bind"); j++)
- {
- // We only want to try bind to a server ip.
- if (Conf.ReadValue("bind","type",j) != "servers")
- continue;
-
- // set current IP to the <bind> tag
- std::string current_ip = Conf.ReadValue("bind","address",j);
-
- // Make sure IP is nothing local
- if (current_ip == "*" || current_ip == "127.0.0.1" || current_ip.empty() || current_ip == "::1")
- continue;
-
- // Try bind, don't fail if it doesn't bind though.
- if (this->DoBindMagic(current_ip))
- return true;
- }
-
- // NOTE: You may wonder WTF we are returning *true* here, but that is because there were no custom binds setup, and so we have nothing to do
- // (remember, outgoing connections without binding are perfectly ok).
- ServerInstance->Logs->Log("SOCKET", DEBUG,"nothing in the config to bind()!");
- return true;
+ // attempt to increase socket sendq and recvq as high as its possible
+ int sendbuf = 32768;
+ int recvbuf = 32768;
+ setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(const char *)&sendbuf,sizeof(sendbuf));
+ setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(const char *)&recvbuf,sizeof(recvbuf));
+ // on failure, do nothing. I'm a little sick of people trying to interpret this message as a result of why their incorrect setups don't work.
}
-bool BufferedSocket::DoConnect(unsigned long maxtime)
+BufferedSocketError BufferedSocket::BeginConnect(const irc::sockets::sockaddrs& dest, const irc::sockets::sockaddrs& bind, unsigned long timeout)
{
- irc::sockets::sockaddrs addr;
- irc::sockets::aptosa(this->host, this->port, &addr);
-
- this->fd = socket(addr.sa.sa_family, SOCK_STREAM, 0);
+ if (fd < 0)
+ fd = socket(dest.sa.sa_family, SOCK_STREAM, 0);
- if (this->fd == -1)
- {
- this->state = I_ERROR;
- this->OnError(I_ERR_SOCKET);
- return false;
- }
+ if (fd < 0)
+ return I_ERR_SOCKET;
- if (!this->BindAddr(this->cbindip))
+ if (bind.sa.sa_family != 0)
{
- this->Close();
- this->fd = -1;
- return false;
+ if (ServerInstance->SE->Bind(fd, &bind.sa, sa_size(bind)) < 0)
+ return I_ERR_BIND;
}
- ServerInstance->SE->NonBlocking(this->fd);
+ ServerInstance->SE->NonBlocking(fd);
- if (ServerInstance->SE->Connect(this, &addr.sa, sa_size(addr)) == -1)
+ if (ServerInstance->SE->Connect(this, &dest.sa, sa_size(dest)) == -1)
{
if (errno != EINPROGRESS)
- {
- this->OnError(I_ERR_CONNECT);
- this->Close();
- this->state = I_ERROR;
- return false;
- }
-
- this->Timeout = new SocketTimeout(this->GetFd(), this->ServerInstance, this, maxtime, this->ServerInstance->Time());
- this->ServerInstance->Timers->AddTimer(this->Timeout);
+ return I_ERR_CONNECT;
}
this->state = I_CONNECTING;
- if (this->fd > -1)
- {
- if (!this->ServerInstance->SE->AddFd(this))
- {
- this->OnError(I_ERR_NOMOREFDS);
- this->Close();
- this->state = I_ERROR;
- return false;
- }
- this->SetQueues();
- }
+
+ if (!ServerInstance->SE->AddFd(this, true))
+ return I_ERR_NOMOREFDS;
+
+ this->Timeout = new SocketTimeout(this->GetFd(), this, timeout, ServerInstance->Time());
+ ServerInstance->Timers->AddTimer(this->Timeout);
+
+ IncreaseOSBuffers(fd);
ServerInstance->Logs->Log("SOCKET", DEBUG,"BufferedSocket::DoConnect success");
- return true;
+ return I_ERR_NONE;
}
-
-void BufferedSocket::Close()
+void StreamSocket::Close()
{
/* Save this, so we dont lose it,
* otherise on failure, error messages
@@ -213,190 +118,196 @@ void BufferedSocket::Close()
int save = errno;
if (this->fd > -1)
{
- if (this->GetIOHook())
+ if (IOHook)
{
try
{
- this->GetIOHook()->OnRawSocketClose(this->fd);
+ IOHook->OnStreamSocketClose(this);
}
catch (CoreException& modexcept)
{
- ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
+ ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s",
+ modexcept.GetSource(), modexcept.GetReason());
}
}
ServerInstance->SE->Shutdown(this, 2);
- if (ServerInstance->SE->Close(this) != -1)
- this->OnClose();
-
- if (ServerInstance->SocketCull.find(this) == ServerInstance->SocketCull.end())
- ServerInstance->SocketCull[this] = this;
+ ServerInstance->SE->DelFd(this);
+ ServerInstance->SE->Close(this);
+ fd = -1;
}
errno = save;
}
-std::string BufferedSocket::GetIP()
+void StreamSocket::cull()
{
- return this->IP;
+ Close();
}
-const char* BufferedSocket::Read()
+bool StreamSocket::GetNextLine(std::string& line, char delim)
{
- if (!ServerInstance->SE->BoundsCheckFd(this))
- return NULL;
-
- int n = 0;
- char* ReadBuffer = ServerInstance->GetReadBuffer();
+ std::string::size_type i = recvq.find(delim);
+ if (i == std::string::npos)
+ return false;
+ line = recvq.substr(0, i - 1);
+ // TODO is this the most efficient way to split?
+ recvq = recvq.substr(i + 1);
+ return true;
+}
- if (this->GetIOHook())
+void StreamSocket::DoRead()
+{
+ if (IOHook)
{
- int result2 = 0;
- int MOD_RESULT = 0;
+ int rv = -1;
try
{
- MOD_RESULT = this->GetIOHook()->OnRawSocketRead(this->fd, ReadBuffer, ServerInstance->Config->NetBufferSize, result2);
+ rv = IOHook->OnStreamSocketRead(this, recvq);
}
catch (CoreException& modexcept)
{
- ServerInstance->Logs->Log("SOCKET", DEFAULT,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
+ ServerInstance->Logs->Log("SOCKET", DEFAULT, "%s threw an exception: %s",
+ modexcept.GetSource(), modexcept.GetReason());
+ return;
}
- if (MOD_RESULT < 0)
+ if (rv > 0)
+ OnDataReady();
+ if (rv < 0)
+ SetError("Read Error"); // will not overwrite a better error message
+ }
+ else
+ {
+ char* ReadBuffer = ServerInstance->GetReadBuffer();
+ int n = recv(fd, ReadBuffer, ServerInstance->Config->NetBufferSize, 0);
+ if (n > 0)
{
- n = -1;
- errno = EAGAIN;
+ recvq.append(ReadBuffer, n);
+ OnDataReady();
}
- else
+ else if (n == 0)
{
- n = result2;
+ error = "Connection closed";
+ }
+ else if (errno != EAGAIN && errno != EINTR)
+ {
+ error = strerror(errno);
}
- }
- else
- {
- n = recv(this->fd, ReadBuffer, ServerInstance->Config->NetBufferSize, 0);
- }
-
- /*
- * This used to do some silly bounds checking instead of just passing bufsize - 1 to recv.
- * Not only does that make absolutely no sense, but it could potentially result in a read buffer's worth
- * of data being thrown into the bit bucket for no good reason, which is just *stupid*.. do things correctly now.
- * --w00t (july 2, 2008)
- */
- if (n > 0)
- {
- ReadBuffer[n] = 0;
- return ReadBuffer;
- }
- else
- {
- int err = errno;
- if (err == EAGAIN)
- return "";
- else
- return NULL;
}
}
-/*
- * This function formerly tried to flush write buffer each call.
- * While admirable in attempting to get the data out to wherever
- * it is going, on a full socket, it's just going to syscall write() and
- * EAGAIN constantly, instead of waiting in the SE to know if it can write
- * which will chew a bit of CPU.
- *
- * So, now this function returns void (take note) and just adds to the sendq.
- *
- * It'll get written at a determinate point when the socketengine tells us it can write.
- * -- w00t (april 1, 2008)
- */
-void BufferedSocket::Write(const std::string &data)
+void StreamSocket::DoWrite()
{
- /* Append the data to the back of the queue ready for writing */
- outbuffer.push_back(data);
-
- /* Mark ourselves as wanting write */
- this->ServerInstance->SE->WantWrite(this);
-}
+ if (sendq.empty())
+ return;
-bool BufferedSocket::FlushWriteBuffer()
-{
- errno = 0;
- if ((this->fd > -1) && (this->state == I_CONNECTED))
+ if (IOHook)
{
- if (this->GetIOHook())
+ int rv = -1;
+ try
{
- while (outbuffer.size() && (errno != EAGAIN))
+ while (!sendq.empty())
{
- try
+ std::string& front = sendq.front();
+ int itemlen = front.length();
+ rv = IOHook->OnStreamSocketWrite(this, front);
+ if (rv > 0)
+ {
+ // consumed the entire string, and is ready for more
+ sendq_len -= itemlen;
+ sendq.pop_front();
+ }
+ else if (rv == 0)
{
- /* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to
- * implement their own buffering mechanisms
- */
- this->GetIOHook()->OnRawSocketWrite(this->fd, outbuffer[0].c_str(), outbuffer[0].length());
- outbuffer.pop_front();
+ // socket has blocked. Stop trying to send data.
+ // IOHook has requested unblock notification from the socketengine
+
+ // Since it is possible that a partial write took place, adjust sendq_len
+ sendq_len = sendq_len - itemlen + front.length();
+ return;
}
- catch (CoreException& modexcept)
+ else
{
- ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
- return true;
+ SetError("Write Error"); // will not overwrite a better error message
+ return;
}
}
}
- else
+ catch (CoreException& modexcept)
{
- /* If we have multiple lines, try to send them all,
- * not just the first one -- Brain
- */
- while (outbuffer.size() && (errno != EAGAIN))
+ ServerInstance->Logs->Log("SOCKET", DEBUG,"%s threw an exception: %s",
+ modexcept.GetSource(), modexcept.GetReason());
+ }
+ }
+ else
+ {
+ // Prepare a writev() call to write all buffers efficiently
+ int bufcount = sendq.size();
+
+ // cap the number of buffers at IOV_MAX
+ if (bufcount > IOV_MAX)
+ bufcount = IOV_MAX;
+
+ iovec* iovecs = new iovec[bufcount];
+ for(int i=0; i < bufcount; i++)
+ {
+ iovecs[i].iov_base = const_cast<char*>(sendq[i].data());
+ iovecs[i].iov_len = sendq[i].length();
+ }
+ int rv = writev(fd, iovecs, bufcount);
+ delete[] iovecs;
+ if (rv == (int)sendq_len)
+ {
+ // it's our lucky day, everything got written out. Fast cleanup.
+ sendq_len = 0;
+ sendq.clear();
+ }
+ else if (rv > 0)
+ {
+ // Partial write. Clean out strings from the sendq
+ sendq_len -= rv;
+ while (rv > 0 && !sendq.empty())
{
- /* Send a line */
- int result = ServerInstance->SE->Send(this, outbuffer[0].c_str(), outbuffer[0].length(), 0);
-
- if (result > 0)
+ std::string& front = sendq.front();
+ if (front.length() < (size_t)rv)
{
- if ((unsigned int)result >= outbuffer[0].length())
- {
- /* The whole block was written (usually a line)
- * Pop the block off the front of the queue,
- * dont set errno, because we are clear of errors
- * and want to try and write the next block too.
- */
- outbuffer.pop_front();
- }
- else
- {
- std::string temp = outbuffer[0].substr(result);
- outbuffer[0] = temp;
- /* We didnt get the whole line out. arses.
- * Try again next time, i guess. Set errno,
- * because we shouldnt be writing any more now,
- * until the socketengine says its safe to do so.
- */
- errno = EAGAIN;
- }
+ // this string got fully written out
+ rv -= front.length();
+ sendq.pop_front();
}
- else if (result == 0)
+ else
{
- this->ServerInstance->SE->DelFd(this);
- this->Close();
- return true;
- }
- else if ((result == -1) && (errno != EAGAIN))
- {
- this->OnError(I_ERR_WRITE);
- this->state = I_ERROR;
- this->ServerInstance->SE->DelFd(this);
- this->Close();
- return true;
+ // stopped in the middle of this string
+ front = front.substr(rv);
+ rv = 0;
}
}
}
+ else if (rv == 0)
+ {
+ error = "Connection closed";
+ }
+ else if (errno != EAGAIN && errno != EINTR)
+ {
+ error = strerror(errno);
+ }
+ if (sendq_len && error.empty())
+ ServerInstance->SE->WantWrite(this);
}
+}
+
+void StreamSocket::WriteData(const std::string &data)
+{
+ bool newWrite = sendq.empty() && !data.empty();
- if ((errno == EAGAIN) && (fd > -1))
+ /* Append the data to the back of the queue ready for writing */
+ sendq.push_back(data);
+ sendq_len += data.length();
+
+ if (newWrite)
{
- this->ServerInstance->SE->WantWrite(this);
+ // TODO perhaps we should try writing first, before asking SE about writes?
+ // DoWrite();
+ ServerInstance->SE->WantWrite(this);
}
-
- return (fd < 0);
}
void SocketTimeout::Tick(time_t)
@@ -421,57 +332,26 @@ void SocketTimeout::Tick(time_t)
*/
this->sock->state = I_ERROR;
- if (ServerInstance->SocketCull.find(this->sock) == ServerInstance->SocketCull.end())
- ServerInstance->SocketCull[this->sock] = this->sock;
+ ServerInstance->GlobalCulls.AddItem(sock);
}
this->sock->Timeout = NULL;
}
-bool BufferedSocket::InternalMarkConnected()
-{
- /* Our socket was in write-state, so delete it and re-add it
- * in read-state.
- */
- this->SetState(I_CONNECTED);
+void BufferedSocket::OnConnected() { }
+void BufferedSocket::OnTimeout() { return; }
- if (this->GetIOHook())
+void BufferedSocket::DoWrite()
+{
+ if (state == I_CONNECTING)
{
- ServerInstance->Logs->Log("SOCKET",DEBUG,"Hook for raw connect");
- try
- {
- this->GetIOHook()->OnRawSocketConnect(this->fd);
- }
- catch (CoreException& modexcept)
- {
- ServerInstance->Logs->Log("SOCKET",DEBUG,"%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
- return false;
- }
+ state = I_CONNECTED;
+ this->OnConnected();
+ if (GetIOHook())
+ GetIOHook()->OnStreamSocketConnect(this);
}
- return this->OnConnected();
-}
-
-void BufferedSocket::SetState(BufferedSocketState s)
-{
- this->state = s;
-}
-
-BufferedSocketState BufferedSocket::GetState()
-{
- return this->state;
-}
-
-bool BufferedSocket::OnConnected() { return true; }
-void BufferedSocket::OnError(BufferedSocketError) { return; }
-int BufferedSocket::OnDisconnect() { return 0; }
-bool BufferedSocket::OnDataReady() { return true; }
-bool BufferedSocket::OnWriteReady()
-{
- // Default behaviour: just try write some.
- return !this->FlushWriteBuffer();
+ this->StreamSocket::DoWrite();
}
-void BufferedSocket::OnTimeout() { return; }
-void BufferedSocket::OnClose() { return; }
BufferedSocket::~BufferedSocket()
{
@@ -483,68 +363,49 @@ BufferedSocket::~BufferedSocket()
}
}
-void BufferedSocket::HandleEvent(EventType et, int errornum)
+void StreamSocket::HandleEvent(EventType et, int errornum)
{
+ BufferedSocketError errcode = I_ERR_OTHER;
switch (et)
{
case EVENT_ERROR:
{
+ SetError(strerror(errornum));
switch (errornum)
{
case ETIMEDOUT:
- this->OnError(I_ERR_TIMEOUT);
+ errcode = I_ERR_TIMEOUT;
break;
case ECONNREFUSED:
case 0:
- this->OnError(this->state == I_CONNECTING ? I_ERR_CONNECT : I_ERR_WRITE);
+ errcode = I_ERR_CONNECT;
break;
case EADDRINUSE:
- this->OnError(I_ERR_BIND);
+ errcode = I_ERR_BIND;
break;
case EPIPE:
case EIO:
- this->OnError(I_ERR_WRITE);
+ errcode = I_ERR_WRITE;
break;
}
-
- if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end())
- this->ServerInstance->SocketCull[this] = this;
- return;
break;
}
case EVENT_READ:
{
- if (!this->OnDataReady())
- {
- if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end())
- this->ServerInstance->SocketCull[this] = this;
- return;
- }
+ DoRead();
break;
}
case EVENT_WRITE:
{
- if (this->state == I_CONNECTING)
- {
- if (!this->InternalMarkConnected())
- {
- if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end())
- this->ServerInstance->SocketCull[this] = this;
- return;
- }
- return;
- }
- else
- {
- if (!this->OnWriteReady())
- {
- if (this->ServerInstance->SocketCull.find(this) == this->ServerInstance->SocketCull.end())
- this->ServerInstance->SocketCull[this] = this;
- return;
- }
- }
+ DoWrite();
break;
}
}
+ if (!error.empty())
+ {
+ ServerInstance->Logs->Log("SOCKET", DEBUG, "Error on FD %d - '%s'", fd, error.c_str());
+ OnError(errcode);
+ ServerInstance->GlobalCulls.AddItem(this);
+ }
}
diff --git a/src/modules.cpp b/src/modules.cpp
index 51fecb47c..c11b63bec 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -159,11 +159,11 @@ void Module::OnGlobalOper(User*) { }
void Module::OnPostConnect(User*) { }
ModResult Module::OnAddBan(User*, Channel*, const std::string &) { return MOD_RES_PASSTHRU; }
ModResult Module::OnDelBan(User*, Channel*, const std::string &) { return MOD_RES_PASSTHRU; }
-void Module::OnRawSocketAccept(int, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { }
-int Module::OnRawSocketWrite(int, const char*, int) { return 0; }
-void Module::OnRawSocketClose(int) { }
-void Module::OnRawSocketConnect(int) { }
-int Module::OnRawSocketRead(int, char*, unsigned int, int&) { return 0; }
+void Module::OnStreamSocketAccept(StreamSocket*, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*) { }
+int Module::OnStreamSocketWrite(StreamSocket*, std::string&) { return -1; }
+void Module::OnStreamSocketClose(StreamSocket*) { }
+void Module::OnStreamSocketConnect(StreamSocket*) { }
+int Module::OnStreamSocketRead(StreamSocket*, std::string&) { return -1; }
void Module::OnUserMessage(User*, void*, int, const std::string&, char, const CUList&) { }
void Module::OnUserNotice(User*, void*, int, const std::string&, char, const CUList&) { }
void Module::OnRemoteKill(User*, User*, const std::string&, const std::string&) { }
@@ -196,7 +196,7 @@ void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { }
void Module::OnRunTestSuite() { }
void Module::OnNamesListItem(User*, Membership*, std::string&, std::string&) { }
ModResult Module::OnNumeric(User*, unsigned int, const std::string&) { return MOD_RES_PASSTHRU; }
-void Module::OnHookIO(EventHandler*, ListenSocketBase*) { }
+void Module::OnHookIO(StreamSocket*, ListenSocketBase*) { }
ModResult Module::OnHostCycle(User*) { return MOD_RES_PASSTHRU; }
void Module::OnSendWhoLine(User*, User*, Channel*, std::string&) { }
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index f458f5da1..27c466573 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -56,7 +56,6 @@ public:
gnutls_session_t sess;
issl_status status;
- std::string outbuf;
};
class CommandStartTLS : public Command
@@ -83,7 +82,7 @@ class CommandStartTLS : public Command
{
user->WriteNumeric(670, "%s :STARTTLS successful, go ahead with TLS handshake", user->nick.c_str());
user->AddIOHook(creator);
- creator->OnRawSocketAccept(user->GetFd(), NULL, NULL);
+ creator->OnStreamSocketAccept(user, NULL, NULL);
}
else
user->WriteNumeric(691, "%s :STARTTLS failure", user->nick.c_str());
@@ -133,16 +132,14 @@ class ModuleSSLGnuTLS : public Module
// Void return, guess we assume success
gnutls_certificate_set_dh_params(x509_cred, dh_params);
- Implementation eventlist[] = { I_On005Numeric, I_OnRawSocketConnect, I_OnRawSocketAccept,
- I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup,
- I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
+ Implementation eventlist[] = { I_On005Numeric, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
I_OnEvent, I_OnHookIO };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
ServerInstance->AddCommand(&starttls);
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
@@ -168,7 +165,7 @@ class ModuleSSLGnuTLS : public Module
sslports.erase(sslports.end() - 1);
}
- virtual void OnModuleRehash(User* user, const std::string &param)
+ void OnModuleRehash(User* user, const std::string &param)
{
if(param != "ssl")
return;
@@ -278,7 +275,7 @@ class ModuleSSLGnuTLS : public Module
ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to generate DH parameters (%d bits): %s", dh_bits, gnutls_strerror(ret));
}
- virtual ~ModuleSSLGnuTLS()
+ ~ModuleSSLGnuTLS()
{
gnutls_x509_crt_deinit(x509_cert);
gnutls_x509_privkey_deinit(x509_key);
@@ -289,7 +286,7 @@ class ModuleSSLGnuTLS : public Module
delete[] sessions;
}
- virtual void OnCleanup(int target_type, void* item)
+ void OnCleanup(int target_type, void* item)
{
if(target_type == TYPE_USER)
{
@@ -305,20 +302,20 @@ class ModuleSSLGnuTLS : public Module
}
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_VENDOR, API_VERSION);
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
if (!sslports.empty())
output.append(" SSL=" + sslports);
output.append(" STARTTLS");
}
- virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb)
+ void OnHookIO(StreamSocket* user, ListenSocketBase* lsb)
{
if (!user->GetIOHook() && listenports.find(lsb) != listenports.end())
{
@@ -327,7 +324,7 @@ class ModuleSSLGnuTLS : public Module
}
}
- virtual const char* OnRequest(Request* request)
+ const char* OnRequest(Request* request)
{
ISHRequest* ISR = static_cast<ISHRequest*>(request);
if (strcmp("IS_NAME", request->GetId()) == 0)
@@ -336,20 +333,13 @@ class ModuleSSLGnuTLS : public Module
}
else if (strcmp("IS_HOOK", request->GetId()) == 0)
{
- const char* ret = "OK";
- try
- {
- ret = ISR->Sock->AddIOHook(this) ? "OK" : NULL;
- }
- catch (ModuleException &e)
- {
- return NULL;
- }
- return ret;
+ ISR->Sock->AddIOHook(this);
+ return "OK";
}
else if (strcmp("IS_UNHOOK", request->GetId()) == 0)
{
- return ISR->Sock->DelIOHook() ? "OK" : NULL;
+ ISR->Sock->DelIOHook();
+ return "OK";
}
else if (strcmp("IS_HSDONE", request->GetId()) == 0)
{
@@ -383,12 +373,9 @@ class ModuleSSLGnuTLS : public Module
}
- virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
+ void OnStreamSocketAccept(StreamSocket* user, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return;
-
+ int fd = user->GetFd();
issl_session* session = &sessions[fd];
/* For STARTTLS: Don't try and init a session on a socket that already has a session */
@@ -405,77 +392,67 @@ class ModuleSSLGnuTLS : public Module
gnutls_certificate_server_set_request(session->sess, GNUTLS_CERT_REQUEST); // Request client certificate if any.
- Handshake(session, fd);
+ Handshake(session, user);
}
- virtual void OnRawSocketConnect(int fd)
+ void OnStreamSocketConnect(StreamSocket* user)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return;
-
- issl_session* session = &sessions[fd];
+ issl_session* session = &sessions[user->GetFd()];
gnutls_init(&session->sess, GNUTLS_CLIENT);
gnutls_set_default_priority(session->sess); // Avoid calling all the priority functions, defaults are adequate.
gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred);
gnutls_dh_set_prime_bits(session->sess, dh_bits);
- gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(fd)); // Give gnutls the fd for the socket.
+ gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(user->GetFd()));
- Handshake(session, fd);
+ Handshake(session, user);
}
- virtual void OnRawSocketClose(int fd)
+ void OnStreamSocketClose(StreamSocket* user)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds()))
- return;
-
- CloseSession(&sessions[fd]);
+ CloseSession(&sessions[user->GetFd()]);
}
- virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
+ int OnStreamSocketRead(StreamSocket* user, std::string& recvq)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return 0;
-
- issl_session* session = &sessions[fd];
+ issl_session* session = &sessions[user->GetFd()];
if (!session->sess)
{
- readresult = 0;
CloseSession(session);
- return 1;
+ user->SetError("No SSL session");
+ return -1;
}
if (session->status == ISSL_HANDSHAKING_READ)
{
// The handshake isn't finished, try to finish it.
- if(!Handshake(session, fd))
+ if(!Handshake(session, user))
{
- errno = session->status == ISSL_CLOSING ? EIO : EAGAIN;
- // Couldn't resume handshake.
+ if (session->status != ISSL_CLOSING)
+ return 0;
+ user->SetError("Handshake Failed");
return -1;
}
}
else if (session->status == ISSL_HANDSHAKING_WRITE)
{
- errno = EAGAIN;
- MakePollWrite(fd);
- return -1;
+ MakePollWrite(user);
+ return 0;
}
// If we resumed the handshake then session->status will be ISSL_HANDSHAKEN.
if (session->status == ISSL_HANDSHAKEN)
{
- unsigned int len = 0;
- while (len < count)
+ char* buffer = ServerInstance->GetReadBuffer();
+ size_t bufsiz = ServerInstance->Config->NetBufferSize;
+ size_t len = 0;
+ while (len < bufsiz)
{
- int ret = gnutls_record_recv(session->sess, buffer + len, count - len);
+ int ret = gnutls_record_recv(session->sess, buffer + len, bufsiz - len);
if (ret > 0)
{
len += ret;
@@ -484,60 +461,49 @@ class ModuleSSLGnuTLS : public Module
{
break;
}
+ else if (ret == 0)
+ {
+ user->SetError("SSL Connection closed");
+ CloseSession(session);
+ return -1;
+ }
else
{
- if (ret != 0)
- ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT,
- "m_ssl_gnutls.so: Error while reading on fd %d: %s",
- fd, gnutls_strerror(ret));
-
- // if ret == 0, client closed connection.
- readresult = 0;
+ user->SetError(gnutls_strerror(ret));
CloseSession(session);
- return 1;
+ return -1;
}
}
- readresult = len;
if (len)
{
+ recvq.append(buffer, len);
return 1;
}
- else
- {
- errno = EAGAIN;
- return -1;
- }
}
else if (session->status == ISSL_CLOSING)
- readresult = 0;
+ return -1;
- return 1;
+ return 0;
}
- virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
+ int OnStreamSocketWrite(StreamSocket* user, std::string& sendq)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return 0;
-
- issl_session* session = &sessions[fd];
- const char* sendbuffer = buffer;
+ issl_session* session = &sessions[user->GetFd()];
if (!session->sess)
{
CloseSession(session);
- return 1;
+ user->SetError("No SSL session");
+ return -1;
}
- session->outbuf.append(sendbuffer, count);
- sendbuffer = session->outbuf.c_str();
- count = session->outbuf.size();
-
if (session->status == ISSL_HANDSHAKING_WRITE || session->status == ISSL_HANDSHAKING_READ)
{
// The handshake isn't finished, try to finish it.
- Handshake(session, fd);
- errno = session->status == ISSL_CLOSING ? EIO : EAGAIN;
+ Handshake(session, user);
+ if (session->status != ISSL_CLOSING)
+ return 0;
+ user->SetError("Handshake Failed");
return -1;
}
@@ -545,42 +511,41 @@ class ModuleSSLGnuTLS : public Module
if (session->status == ISSL_HANDSHAKEN)
{
- ret = gnutls_record_send(session->sess, sendbuffer, count);
+ ret = gnutls_record_send(session->sess, sendq.data(), sendq.length());
- if (ret == 0)
+ if (ret == (int)sendq.length())
{
- CloseSession(session);
+ return 1;
}
- else if (ret < 0)
+ else if (ret > 0)
{
- if(ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED)
- {
- ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT,
- "m_ssl_gnutls.so: Error while writing to fd %d: %s",
- fd, gnutls_strerror(ret));
- CloseSession(session);
- }
- else
- {
- errno = EAGAIN;
- }
+ sendq = sendq.substr(ret);
+ MakePollWrite(user);
+ return 0;
}
- else
+ else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
+ {
+ MakePollWrite(user);
+ return 0;
+ }
+ else if (ret == 0)
{
- session->outbuf = session->outbuf.substr(ret);
+ CloseSession(session);
+ user->SetError("SSL Connection closed");
+ return -1;
+ }
+ else // (ret < 0)
+ {
+ user->SetError(gnutls_strerror(ret));
+ CloseSession(session);
+ return -1;
}
}
- if (!session->outbuf.empty())
- MakePollWrite(fd);
-
- /* Who's smart idea was it to return 1 when we havent written anything?
- * This fucks the buffer up in BufferedSocket :p
- */
- return ret < 1 ? 0 : ret;
+ return 0;
}
- bool Handshake(issl_session* session, int fd)
+ bool Handshake(issl_session* session, EventHandler* user)
{
int ret = gnutls_handshake(session->sess);
@@ -599,15 +564,11 @@ class ModuleSSLGnuTLS : public Module
{
// gnutls_handshake() wants to write() again.
session->status = ISSL_HANDSHAKING_WRITE;
- MakePollWrite(fd);
+ MakePollWrite(user);
}
}
else
{
- // Handshake failed.
- ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT,
- "m_ssl_gnutls.so: Handshake failed on fd %d: %s",
- fd, gnutls_strerror(ret));
CloseSession(session);
session->status = ISSL_CLOSING;
}
@@ -619,18 +580,16 @@ class ModuleSSLGnuTLS : public Module
// Change the seesion state
session->status = ISSL_HANDSHAKEN;
- EventHandler* user = ServerInstance->SE->GetRef(fd);
-
VerifyCertificate(session,user);
// Finish writing, if any left
- MakePollWrite(fd);
+ MakePollWrite(user);
return true;
}
}
- virtual void OnPostConnect(User* user)
+ void OnPostConnect(User* user)
{
// This occurs AFTER OnUserConnect so we can be sure the
// protocol module has propagated the NICK message.
@@ -646,22 +605,9 @@ class ModuleSSLGnuTLS : public Module
}
}
- void MakePollWrite(int fd)
+ void MakePollWrite(EventHandler* eh)
{
- //OnRawSocketWrite(fd, NULL, 0);
- EventHandler* eh = ServerInstance->SE->GetRef(fd);
- if (eh)
- ServerInstance->SE->WantWrite(eh);
- }
-
- virtual void OnBufferFlushed(User* user)
- {
- if (user->GetIOHook() == this)
- {
- issl_session* session = &sessions[user->GetFd()];
- if (session && session->outbuf.size())
- OnRawSocketWrite(user->GetFd(), NULL, 0);
- }
+ ServerInstance->SE->WantWrite(eh);
}
void CloseSession(issl_session* session)
@@ -672,7 +618,6 @@ class ModuleSSLGnuTLS : public Module
gnutls_deinit(session->sess);
}
- session->outbuf.clear();
session->sess = NULL;
session->status = ISSL_NONE;
}
diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp
index a33cf6bc2..e77fa23ff 100644
--- a/src/modules/extra/m_ssl_openssl.cpp
+++ b/src/modules/extra/m_ssl_openssl.cpp
@@ -59,7 +59,7 @@ public:
unsigned int inbufoffset;
char* inbuf; // Buffer OpenSSL reads into.
- std::string outbuf; // Buffer for outgoing data that OpenSSL will not take.
+ std::string outbuf;
int fd;
bool outbound;
@@ -95,7 +95,6 @@ class ModuleSSLOpenSSL : public Module
SSL_CTX* ctx;
SSL_CTX* clictx;
- char* dummy;
char cipher[MAXBUF];
std::string keyfile;
@@ -137,14 +136,13 @@ class ModuleSSLOpenSSL : public Module
// Needs the flag as it ignores a plain /rehash
OnModuleRehash(NULL,"ssl");
- Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept,
- I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnCleanup, I_On005Numeric,
- I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
+ Implementation eventlist[] = {
+ I_On005Numeric, I_OnBufferFlushed, I_OnRequest, I_OnRehash, I_OnModuleRehash, I_OnPostConnect,
I_OnHookIO };
ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
}
- virtual void OnHookIO(EventHandler* user, ListenSocketBase* lsb)
+ void OnHookIO(StreamSocket* user, ListenSocketBase* lsb)
{
if (!user->GetIOHook() && listenports.find(lsb) != listenports.end())
{
@@ -153,7 +151,7 @@ class ModuleSSLOpenSSL : public Module
}
}
- virtual void OnRehash(User* user)
+ void OnRehash(User* user)
{
ConfigReader Conf(ServerInstance);
@@ -179,7 +177,7 @@ class ModuleSSLOpenSSL : public Module
sslports.erase(sslports.end() - 1);
}
- virtual void OnModuleRehash(User* user, const std::string &param)
+ void OnModuleRehash(User* user, const std::string &param)
{
if (param != "ssl")
return;
@@ -266,13 +264,13 @@ class ModuleSSLOpenSSL : public Module
fclose(dhpfile);
}
- virtual void On005Numeric(std::string &output)
+ void On005Numeric(std::string &output)
{
if (!sslports.empty())
output.append(" SSL=" + sslports);
}
- virtual ~ModuleSSLOpenSSL()
+ ~ModuleSSLOpenSSL()
{
SSL_CTX_free(ctx);
SSL_CTX_free(clictx);
@@ -280,7 +278,7 @@ class ModuleSSLOpenSSL : public Module
delete[] sessions;
}
- virtual void OnCleanup(int target_type, void* item)
+ void OnCleanup(int target_type, void* item)
{
if (target_type == TYPE_USER)
{
@@ -296,13 +294,13 @@ class ModuleSSLOpenSSL : public Module
}
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_VENDOR, API_VERSION);
}
- virtual const char* OnRequest(Request* request)
+ const char* OnRequest(Request* request)
{
ISHRequest* ISR = (ISHRequest*)request;
if (strcmp("IS_NAME", request->GetId()) == 0)
@@ -311,21 +309,13 @@ class ModuleSSLOpenSSL : public Module
}
else if (strcmp("IS_HOOK", request->GetId()) == 0)
{
- const char* ret = "OK";
- try
- {
- ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL;
- }
- catch (ModuleException &e)
- {
- return NULL;
- }
-
- return ret;
+ ISR->Sock->AddIOHook(this);
+ return "OK";
}
else if (strcmp("IS_UNHOOK", request->GetId()) == 0)
{
- return ISR->Sock->DelIOHook() ? "OK" : NULL;
+ ISR->Sock->DelIOHook();
+ return "OK";
}
else if (strcmp("IS_HSDONE", request->GetId()) == 0)
{
@@ -353,11 +343,9 @@ class ModuleSSLOpenSSL : public Module
}
- virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
+ void OnStreamSocketAccept(StreamSocket* user, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
{
- /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return;
+ int fd = user->GetFd();
issl_session* session = &sessions[fd];
@@ -377,11 +365,12 @@ class ModuleSSLOpenSSL : public Module
return;
}
- Handshake(session);
+ Handshake(user, session);
}
- virtual void OnRawSocketConnect(int fd)
+ void OnStreamSocketConnect(StreamSocket* user)
{
+ int fd = user->GetFd();
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() -1))
return;
@@ -404,11 +393,12 @@ class ModuleSSLOpenSSL : public Module
return;
}
- Handshake(session);
+ Handshake(user, session);
}
- virtual void OnRawSocketClose(int fd)
+ void OnStreamSocketClose(StreamSocket* user)
{
+ int fd = user->GetFd();
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
return;
@@ -416,19 +406,19 @@ class ModuleSSLOpenSSL : public Module
CloseSession(&sessions[fd]);
}
- virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
+ int OnStreamSocketRead(StreamSocket* user, std::string& recvq)
{
+ int fd = user->GetFd();
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return 0;
+ return -1;
issl_session* session = &sessions[fd];
if (!session->sess)
{
- readresult = 0;
CloseSession(session);
- return 1;
+ return -1;
}
if (session->status == ISSL_HANDSHAKING)
@@ -436,17 +426,17 @@ class ModuleSSLOpenSSL : public Module
if (session->rstat == ISSL_READ || session->wstat == ISSL_READ)
{
// The handshake isn't finished and it wants to read, try to finish it.
- if (!Handshake(session))
+ if (!Handshake(user, session))
{
// Couldn't resume handshake.
- errno = session->status == ISSL_NONE ? EIO : EAGAIN;
- return -1;
+ if (session->status == ISSL_NONE)
+ return -1;
+ return 0;
}
}
else
{
- errno = EAGAIN;
- return -1;
+ return 0;
}
}
@@ -456,51 +446,37 @@ class ModuleSSLOpenSSL : public Module
{
if (session->wstat == ISSL_READ)
{
- if(DoWrite(session) == 0)
+ if(DoWrite(user, session) == 0)
return 0;
}
if (session->rstat == ISSL_READ)
{
- int ret = DoRead(session);
+ int ret = DoRead(user, session);
if (ret > 0)
{
- if (count <= session->inbufoffset)
- {
- memcpy(buffer, session->inbuf, count);
- // Move the stuff left in inbuf to the beginning of it
- memmove(session->inbuf, session->inbuf + count, (session->inbufoffset - count));
- // Now we need to set session->inbufoffset to the amount of data still waiting to be handed to insp.
- session->inbufoffset -= count;
- // Insp uses readresult as the count of how much data there is in buffer, so:
- readresult = count;
- }
- else
- {
- // There's not as much in the inbuf as there is space in the buffer, so just copy the whole thing.
- memcpy(buffer, session->inbuf, session->inbufoffset);
-
- readresult = session->inbufoffset;
- // Zero the offset, as there's nothing there..
- session->inbufoffset = 0;
- }
+ recvq.append(session->inbuf, session->inbufoffset);
+ session->inbufoffset = 0;
return 1;
}
- return ret;
+ else if (errno == EAGAIN || errno == EINTR)
+ return 0;
+ else
+ return -1;
}
}
- return -1;
+ return 0;
}
- virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
+ int OnStreamSocketWrite(StreamSocket* user, std::string& buffer)
{
+ int fd = user->GetFd();
/* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return 0;
+ return -1;
- errno = EAGAIN;
issl_session* session = &sessions[fd];
if (!session->sess)
@@ -509,40 +485,53 @@ class ModuleSSLOpenSSL : public Module
return -1;
}
- session->outbuf.append(buffer, count);
- MakePollWrite(session);
-
if (session->status == ISSL_HANDSHAKING)
{
// The handshake isn't finished, try to finish it.
if (session->rstat == ISSL_WRITE || session->wstat == ISSL_WRITE)
{
- if (!Handshake(session))
+ if (!Handshake(user, session))
{
// Couldn't resume handshake.
- errno = session->status == ISSL_NONE ? EIO : EAGAIN;
- return -1;
+ if (session->status == ISSL_NONE)
+ return -1;
+ return 0;
}
}
}
+ int rv = 0;
+
+ // don't pull items into the output buffer until they are
+ // unlikely to block; this allows sendq exceeded to continue
+ // to work for SSL users.
+ // TODO better signaling for I/O requests so this isn't needed
+ if (session->outbuf.empty())
+ {
+ session->outbuf = buffer;
+ rv = 1;
+ }
+
if (session->status == ISSL_OPEN)
{
if (session->rstat == ISSL_WRITE)
{
- DoRead(session);
+ DoRead(user, session);
}
if (session->wstat == ISSL_WRITE)
{
- return DoWrite(session);
+ DoWrite(user, session);
}
}
- return 1;
+ if (rv == 0 || !session->outbuf.empty())
+ ServerInstance->SE->WantWrite(user);
+
+ return rv;
}
- int DoWrite(issl_session* session)
+ int DoWrite(StreamSocket* user, issl_session* session)
{
if (!session->outbuf.size())
return -1;
@@ -561,6 +550,7 @@ class ModuleSSLOpenSSL : public Module
if (err == SSL_ERROR_WANT_WRITE)
{
session->wstat = ISSL_WRITE;
+ ServerInstance->SE->WantWrite(user);
return -1;
}
else if (err == SSL_ERROR_WANT_READ)
@@ -581,7 +571,7 @@ class ModuleSSLOpenSSL : public Module
}
}
- int DoRead(issl_session* session)
+ int DoRead(StreamSocket* user, issl_session* session)
{
// Is this right? Not sure if the unencrypted data is garaunteed to be the same length.
// Read into the inbuffer, offset from the beginning by the amount of data we have that insp hasn't taken yet.
@@ -606,7 +596,7 @@ class ModuleSSLOpenSSL : public Module
else if (err == SSL_ERROR_WANT_WRITE)
{
session->rstat = ISSL_WRITE;
- MakePollWrite(session);
+ ServerInstance->SE->WantWrite(user);
return -1;
}
else
@@ -627,7 +617,7 @@ class ModuleSSLOpenSSL : public Module
}
}
- bool Handshake(issl_session* session)
+ bool Handshake(EventHandler* user, issl_session* session)
{
int ret;
@@ -650,7 +640,7 @@ class ModuleSSLOpenSSL : public Module
{
session->wstat = ISSL_WRITE;
session->status = ISSL_HANDSHAKING;
- MakePollWrite(session);
+ ServerInstance->SE->WantWrite(user);
return true;
}
else
@@ -669,7 +659,7 @@ class ModuleSSLOpenSSL : public Module
session->status = ISSL_OPEN;
- MakePollWrite(session);
+ ServerInstance->SE->WantWrite(user);
return true;
}
@@ -682,34 +672,14 @@ class ModuleSSLOpenSSL : public Module
return true;
}
- virtual void OnPostConnect(User* user)
- {
- // This occurs AFTER OnUserConnect so we can be sure the
- // protocol module has propagated the NICK message.
- if ((user->GetIOHook() == this) && (IS_LOCAL(user)))
- {
- if (sessions[user->GetFd()].sess)
- user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), SSL_get_cipher(sessions[user->GetFd()].sess));
- }
- }
-
- void MakePollWrite(issl_session* session)
- {
- //OnRawSocketWrite(session->fd, NULL, 0);
- EventHandler* eh = ServerInstance->SE->GetRef(session->fd);
- if (eh)
- {
- ServerInstance->SE->WantWrite(eh);
- }
- }
-
- virtual void OnBufferFlushed(User* user)
+ void OnBufferFlushed(User* user)
{
if (user->GetIOHook() == this)
{
+ std::string dummy;
issl_session* session = &sessions[user->GetFd()];
if (session && session->outbuf.size())
- OnRawSocketWrite(user->GetFd(), NULL, 0);
+ OnStreamSocketWrite(user, dummy);
}
}
diff --git a/src/modules/extra/m_ziplink.cpp b/src/modules/extra/m_ziplink.cpp
index c220460bd..7d090d80a 100644
--- a/src/modules/extra/m_ziplink.cpp
+++ b/src/modules/extra/m_ziplink.cpp
@@ -67,29 +67,29 @@ class ModuleZLib : public Module
total_out_compressed = total_in_compressed = 0;
total_out_uncompressed = total_in_uncompressed = 0;
- Implementation eventlist[] = { I_OnRawSocketConnect, I_OnRawSocketAccept, I_OnRawSocketClose, I_OnRawSocketRead, I_OnRawSocketWrite, I_OnStats, I_OnRequest };
- ServerInstance->Modules->Attach(eventlist, this, 7);
+ Implementation eventlist[] = { I_OnStats, I_OnRequest };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
// Allocate a buffer which is used for reading and writing data
net_buffer_size = ServerInstance->Config->NetBufferSize;
net_buffer = new char[net_buffer_size];
}
- virtual ~ModuleZLib()
+ ~ModuleZLib()
{
ServerInstance->Modules->UnpublishInterface("BufferedSocketHook", this);
delete[] sessions;
delete[] net_buffer;
}
- virtual Version GetVersion()
+ Version GetVersion()
{
return Version("$Id$", VF_VENDOR, API_VERSION);
}
/* Handle BufferedSocketHook API requests */
- virtual const char* OnRequest(Request* request)
+ const char* OnRequest(Request* request)
{
ISHRequest* ISR = (ISHRequest*)request;
if (strcmp("IS_NAME", request->GetId()) == 0)
@@ -99,22 +99,13 @@ class ModuleZLib : public Module
}
else if (strcmp("IS_HOOK", request->GetId()) == 0)
{
- /* Attach to an inspsocket */
- const char* ret = "OK";
- try
- {
- ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL;
- }
- catch (ModuleException& e)
- {
- return NULL;
- }
- return ret;
+ ISR->Sock->AddIOHook(this);
+ return "OK";
}
else if (strcmp("IS_UNHOOK", request->GetId()) == 0)
{
- /* Detach from an inspsocket */
- return ISR->Sock->DelIOHook() ? "OK" : NULL;
+ ISR->Sock->DelIOHook();
+ return "OK";
}
else if (strcmp("IS_HSDONE", request->GetId()) == 0)
{
@@ -134,7 +125,7 @@ class ModuleZLib : public Module
}
/* Handle stats z (misc stats) */
- virtual ModResult OnStats(char symbol, User* user, string_list &results)
+ ModResult OnStats(char symbol, User* user, string_list &results)
{
if (symbol == 'z')
{
@@ -174,10 +165,14 @@ class ModuleZLib : public Module
return MOD_RES_PASSTHRU;
}
- virtual void OnRawSocketConnect(int fd)
+ void OnStreamSocketConnect(StreamSocket* user)
{
- if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
- return;
+ OnStreamSocketAccept(user, 0, 0);
+ }
+
+ void OnRawSocketAccept(StreamSocket* user, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*)
+ {
+ int fd = user->GetFd();
izip_session* session = &sessions[fd];
@@ -211,39 +206,33 @@ class ModuleZLib : public Module
session->status = IZIP_OPEN;
}
- virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs*, irc::sockets::sockaddrs*)
- {
- /* Nothing special needs doing here compared to connect() */
- OnRawSocketConnect(fd);
- }
-
- virtual void OnRawSocketClose(int fd)
+ void OnStreamSocketClose(StreamSocket* user)
{
+ int fd = user->GetFd();
CloseSession(&sessions[fd]);
}
- virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
+ int OnStreamSocketRead(StreamSocket* user, std::string& recvq)
{
+ int fd = user->GetFd();
/* Find the sockets session */
izip_session* session = &sessions[fd];
if (session->status == IZIP_CLOSED)
- return 0;
+ return -1;
- if (session->inbuf.length())
- {
- /* Our input buffer is filling up. This is *BAD*.
- * We can't return more data than fits into buffer
- * (count bytes), so we will generate another read
- * event on purpose by *NOT* reading from 'fd' at all
- * for now.
- */
- readresult = 0;
- }
- else
+ if (session->inbuf.empty())
{
/* Read read_buffer_size bytes at a time to the buffer (usually 2.5k) */
- readresult = read(fd, net_buffer, net_buffer_size);
+ int readresult = read(fd, net_buffer, net_buffer_size);
+
+ if (readresult < 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ return 0;
+ }
+ if (readresult <= 0)
+ return -1;
total_in_compressed += readresult;
@@ -252,10 +241,8 @@ class ModuleZLib : public Module
}
size_t in_len = session->inbuf.length();
-
- /* Do we have anything to do? */
- if (in_len <= 0)
- return 0;
+ char* buffer = ServerInstance->GetReadBuffer();
+ int count = ServerInstance->Config->NetBufferSize;
/* Prepare decompression */
session->d_stream.next_in = (Bytef *)session->inbuf.c_str();
@@ -302,8 +289,7 @@ class ModuleZLib : public Module
}
if (ret != Z_OK)
{
- readresult = 0;
- return 0;
+ return -1;
}
/* Update the inbut buffer */
@@ -315,24 +301,18 @@ class ModuleZLib : public Module
total_in_uncompressed += uncompressed_length;
/* Null-terminate the buffer -- this doesnt harm binary data */
- buffer[uncompressed_length] = 0;
-
- /* Set the read size to the correct total size */
- readresult = uncompressed_length;
-
+ recvq.append(buffer, uncompressed_length);
return 1;
}
- virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
+ int OnStreamSocketWrite(StreamSocket* user, std::string& sendq)
{
+ int fd = user->GetFd();
izip_session* session = &sessions[fd];
- if (!count) /* Nothing to do! */
- return 0;
-
if(session->status != IZIP_OPEN)
/* Seriously, wtf? */
- return 0;
+ return -1;
int ret;
@@ -343,8 +323,8 @@ class ModuleZLib : public Module
do
{
/* Prepare compression */
- session->c_stream.next_in = (Bytef*)buffer + offset;
- session->c_stream.avail_in = count - offset;
+ session->c_stream.next_in = (Bytef*)sendq.data() + offset;
+ session->c_stream.avail_in = sendq.length() - offset;
session->c_stream.next_out = (Bytef*)net_buffer;
session->c_stream.avail_out = net_buffer_size;
@@ -378,7 +358,7 @@ class ModuleZLib : public Module
/* Space before - space after stuff was added to this */
unsigned int compressed = net_buffer_size - session->c_stream.avail_out;
- unsigned int uncompressed = count - session->c_stream.avail_in;
+ unsigned int uncompressed = sendq.length() - session->c_stream.avail_in;
/* Make it skip the data which was compressed already */
offset += uncompressed;
@@ -404,14 +384,11 @@ class ModuleZLib : public Module
else
{
session->outbuf.clear();
- return 0;
+ return -1;
}
}
- /* ALL LIES the lot of it, we havent really written
- * this amount, but the layer above doesnt need to know.
- */
- return count;
+ return 1;
}
void Error(izip_session* session, const std::string &text)
diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp
index bdf4e424e..c1698accf 100644
--- a/src/modules/m_httpd.cpp
+++ b/src/modules/m_httpd.cpp
@@ -37,6 +37,7 @@ class HttpServerSocket : public BufferedSocket
{
FileReader* index;
HttpState InternalState;
+ std::string ip;
HTTPHeaders headers;
std::string reqbuffer;
@@ -48,7 +49,8 @@ class HttpServerSocket : public BufferedSocket
public:
- HttpServerSocket(InspIRCd* SI, int newfd, const char* ip, FileReader* ind) : BufferedSocket(SI, newfd, ip), index(ind), postsize(0)
+ HttpServerSocket(int newfd, const char* IP, FileReader* ind)
+ : BufferedSocket(newfd), index(ind), ip(IP), postsize(0)
{
InternalState = HTTP_SERVE_WAIT_REQUEST;
}
@@ -62,7 +64,7 @@ class HttpServerSocket : public BufferedSocket
{
}
- virtual void OnClose()
+ virtual void OnError(BufferedSocketError)
{
}
@@ -164,15 +166,15 @@ class HttpServerSocket : public BufferedSocket
"<small>Powered by <a href='http://www.inspircd.org'>InspIRCd</a></small></body></html>";
SendHeaders(data.length(), response, empty);
- this->Write(data);
+ WriteData(data);
}
void SendHeaders(unsigned long size, int response, HTTPHeaders &rheaders)
{
- this->Write(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n");
+ WriteData(http_version + " "+ConvToStr(response)+" "+Response(response)+"\r\n");
- time_t local = this->ServerInstance->Time();
+ time_t local = ServerInstance->Time();
struct tm *timeinfo = gmtime(&local);
char *date = asctime(timeinfo);
date[strlen(date) - 1] = '\0';
@@ -191,40 +193,32 @@ class HttpServerSocket : public BufferedSocket
*/
rheaders.SetHeader("Connection", "Close");
- this->Write(rheaders.GetFormattedHeaders());
- this->Write("\r\n");
+ WriteData(rheaders.GetFormattedHeaders());
+ WriteData("\r\n");
}
- virtual bool OnDataReady()
+ void OnDataReady()
{
- const char* data = this->Read();
-
- /* Check that the data read is a valid pointer and it has some content */
- if (!data || !*data)
- return false;
-
if (InternalState == HTTP_SERVE_RECV_POSTDATA)
{
- postdata.append(data);
+ postdata.append(recvq);
if (postdata.length() >= postsize)
ServeData();
}
else
{
- reqbuffer.append(data);
+ reqbuffer.append(recvq);
if (reqbuffer.length() >= 8192)
{
ServerInstance->Logs->Log("m_httpd",DEBUG, "m_httpd dropped connection due to an oversized request buffer");
reqbuffer.clear();
- return false;
+ SetError("Buffer");
}
if (InternalState == HTTP_SERVE_WAIT_REQUEST)
CheckRequestBuffer();
}
-
- return true;
}
void CheckRequestBuffer()
@@ -314,18 +308,18 @@ class HttpServerSocket : public BufferedSocket
{
HTTPHeaders empty;
SendHeaders(index->ContentSize(), 200, empty);
- this->Write(index->Contents());
+ WriteData(index->Contents());
}
else
{
claimed = false;
- HTTPRequest httpr(request_type,uri,&headers,this,this->GetIP(),postdata);
+ HTTPRequest httpr(request_type,uri,&headers,this,ip,postdata);
Event acl((char*)&httpr, (Module*)HttpModule, "httpd_acl");
- acl.Send(this->ServerInstance);
+ acl.Send(ServerInstance);
if (!claimed)
{
Event e((char*)&httpr, (Module*)HttpModule, "httpd_url");
- e.Send(this->ServerInstance);
+ e.Send(ServerInstance);
if (!claimed)
{
SendHTTPError(404);
@@ -337,7 +331,7 @@ class HttpServerSocket : public BufferedSocket
void Page(std::stringstream* n, int response, HTTPHeaders *hheaders)
{
SendHeaders(n->str().length(), response, *hheaders);
- this->Write(n->str());
+ WriteData(n->str());
}
};
@@ -358,7 +352,7 @@ class HttpListener : public ListenSocketBase
int port;
std::string incomingip;
irc::sockets::satoap(&client, incomingip, port);
- new HttpServerSocket(ServerInstance, nfd, incomingip.c_str(), index);
+ new HttpServerSocket(nfd, incomingip.c_str(), index);
}
};
@@ -426,7 +420,6 @@ class ModuleHttpServer : public Module
httpsocks[i]->Close();
delete httpsocks[i]->GetIndex();
}
- ServerInstance->BufferedSocketCull();
}
virtual Version GetVersion()
diff --git a/src/modules/m_spanningtree/addline.cpp b/src/modules/m_spanningtree/addline.cpp
index 2f7b5132d..3e6d38070 100644
--- a/src/modules/m_spanningtree/addline.cpp
+++ b/src/modules/m_spanningtree/addline.cpp
@@ -24,7 +24,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
{
if (params.size() < 6)
{
- this->ServerInstance->SNO->WriteToSnoMask('d',"%s sent me a malformed ADDLINE of type %s.",prefix.c_str(),params[0].c_str());
+ ServerInstance->SNO->WriteToSnoMask('d',"%s sent me a malformed ADDLINE of type %s.",prefix.c_str(),params[0].c_str());
return true;
}
@@ -43,7 +43,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
if (!xlf)
{
- this->ServerInstance->SNO->WriteToSnoMask('d',"%s sent me an unknown ADDLINE type (%s).",setter.c_str(),params[0].c_str());
+ ServerInstance->SNO->WriteToSnoMask('d',"%s sent me an unknown ADDLINE type (%s).",setter.c_str(),params[0].c_str());
return true;
}
@@ -54,7 +54,7 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
}
catch (ModuleException &e)
{
- this->ServerInstance->SNO->WriteToSnoMask('d',"Unable to ADDLINE type %s from %s: %s", params[0].c_str(), setter.c_str(), e.GetReason());
+ ServerInstance->SNO->WriteToSnoMask('d',"Unable to ADDLINE type %s from %s: %s", params[0].c_str(), setter.c_str(), e.GetReason());
return true;
}
xl->SetCreateTime(atoi(params[3].c_str()));
@@ -62,12 +62,12 @@ bool TreeSocket::AddLine(const std::string &prefix, parameterlist &params)
{
if (xl->duration)
{
- this->ServerInstance->SNO->WriteToSnoMask('X',"%s added %s%s on %s to expire on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "",
+ ServerInstance->SNO->WriteToSnoMask('X',"%s added %s%s on %s to expire on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "",
params[1].c_str(),ServerInstance->TimeString(xl->expiry).c_str(),params[5].c_str());
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('X',"%s added permanent %s%s on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "",
+ ServerInstance->SNO->WriteToSnoMask('X',"%s added permanent %s%s on %s: %s",setter.c_str(),params[0].c_str(),params[0].length() == 1 ? "-line" : "",
params[1].c_str(),params[5].c_str());
}
params[5] = ":" + params[5];
diff --git a/src/modules/m_spanningtree/admin.cpp b/src/modules/m_spanningtree/admin.cpp
index 133da928b..e47078c7e 100644
--- a/src/modules/m_spanningtree/admin.cpp
+++ b/src/modules/m_spanningtree/admin.cpp
@@ -25,30 +25,30 @@ bool TreeSocket::Admin(const std::string &prefix, parameterlist &params)
{
if (params.size() > 0)
{
- if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
+ if (InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
{
/* It's for our server */
string_list results;
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
{
parameterlist par;
par.push_back(prefix);
par.push_back("");
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName;
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName;
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick;
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail;
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
}
}
else
{
/* Pass it on */
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
Utils->DoOneToOne(prefix, "ADMIN", params, params[0]);
}
diff --git a/src/modules/m_spanningtree/away.cpp b/src/modules/m_spanningtree/away.cpp
index 2aac26bbd..354266554 100644
--- a/src/modules/m_spanningtree/away.cpp
+++ b/src/modules/m_spanningtree/away.cpp
@@ -20,7 +20,7 @@
bool TreeSocket::Away(const std::string &prefix, parameterlist &params)
{
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (!u)
return true;
if (params.size())
diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp
index 66d448e55..7953468e4 100644
--- a/src/modules/m_spanningtree/capab.cpp
+++ b/src/modules/m_spanningtree/capab.cpp
@@ -23,7 +23,7 @@
std::string TreeSocket::MyModules(int filter)
{
- std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(filter);
+ std::vector<std::string> modlist = ServerInstance->Modules->GetAllModuleNames(filter);
if (filter == VF_COMMON && proto_version != ProtocolVersion)
CompatAddModules(modlist);
@@ -236,13 +236,13 @@ bool TreeSocket::Capab(const parameterlist &params)
}
}
- if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != this->ServerInstance->Modes->BuildPrefixes())
+ if(this->CapKeys.find("PREFIX") != this->CapKeys.end() && this->CapKeys.find("PREFIX")->second != ServerInstance->Modes->BuildPrefixes())
reason = "One or more of the prefixes on the remote server are invalid on this server.";
- if(this->CapKeys.find("CHANMODES") != this->CapKeys.end() && this->CapKeys.find("CHANMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_CHANNEL))
+ if(this->CapKeys.find("CHANMODES") != this->CapKeys.end() && this->CapKeys.find("CHANMODES")->second != ServerInstance->Modes->GiveModeList(MASK_CHANNEL))
reason = "One or more of the channel modes on the remote server are invalid on this server.";
- if(this->CapKeys.find("USERMODES") != this->CapKeys.end() && this->CapKeys.find("USERMODES")->second != this->ServerInstance->Modes->GiveModeList(MASK_USER))
+ if(this->CapKeys.find("USERMODES") != this->CapKeys.end() && this->CapKeys.find("USERMODES")->second != ServerInstance->Modes->GiveModeList(MASK_USER))
reason = "One or more of the user modes on the remote server are invalid on this server.";
@@ -255,8 +255,8 @@ bool TreeSocket::Capab(const parameterlist &params)
if (!this->GetTheirChallenge().empty() && (this->LinkState == CONNECTING))
{
this->SendCapabilities(2);
- this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+this->MakePass(OutboundPass, this->GetTheirChallenge())+" 0 "+
- ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc);
+ this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+this->MakePass(OutboundPass, this->GetTheirChallenge())+" 0 "+
+ ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc);
}
}
else
@@ -265,7 +265,7 @@ bool TreeSocket::Capab(const parameterlist &params)
if (this->LinkState == CONNECTING)
{
this->SendCapabilities(2);
- this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+OutboundPass+" 0 "+ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc);
+ this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+OutboundPass+" 0 "+ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc);
}
}
diff --git a/src/modules/m_spanningtree/compat.cpp b/src/modules/m_spanningtree/compat.cpp
index 8a6e6855f..71272edec 100644
--- a/src/modules/m_spanningtree/compat.cpp
+++ b/src/modules/m_spanningtree/compat.cpp
@@ -82,7 +82,7 @@ void TreeSocket::WriteLine(std::string line)
ServerInstance->Logs->Log("m_spanningtree",DEBUG, "S[%d] O %s", this->GetFd(), line.c_str());
line.append("\r\n");
- this->Write(line);
+ this->WriteData(line);
}
diff --git a/src/modules/m_spanningtree/delline.cpp b/src/modules/m_spanningtree/delline.cpp
index a1a9089ad..cadcdd14b 100644
--- a/src/modules/m_spanningtree/delline.cpp
+++ b/src/modules/m_spanningtree/delline.cpp
@@ -42,7 +42,7 @@ bool TreeSocket::DelLine(const std::string &prefix, parameterlist &params)
/* NOTE: No check needed on 'user', this function safely handles NULL */
if (ServerInstance->XLines->DelLine(params[1].c_str(), params[0], user))
{
- this->ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(),
+ ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(),
params[0].c_str(), params[0].length() == 1 ? "-line" : "", params[1].c_str());
Utils->DoOneToAllButSender(prefix,"DELLINE", params, prefix);
}
diff --git a/src/modules/m_spanningtree/encap.cpp b/src/modules/m_spanningtree/encap.cpp
index 7b85a49d0..175257b0a 100644
--- a/src/modules/m_spanningtree/encap.cpp
+++ b/src/modules/m_spanningtree/encap.cpp
@@ -29,7 +29,7 @@ bool TreeSocket::Encap(const std::string &prefix, parameterlist &params)
{
if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0]))
{
- User* who = this->ServerInstance->FindUUID(prefix);
+ User* who = ServerInstance->FindUUID(prefix);
if (!who)
who = Utils->ServerUser;
diff --git a/src/modules/m_spanningtree/fhost.cpp b/src/modules/m_spanningtree/fhost.cpp
index 1595b98aa..d31cffa39 100644
--- a/src/modules/m_spanningtree/fhost.cpp
+++ b/src/modules/m_spanningtree/fhost.cpp
@@ -25,7 +25,7 @@ bool TreeSocket::ChangeHost(const std::string &prefix, parameterlist &params)
{
if (params.size() < 1)
return true;
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
diff --git a/src/modules/m_spanningtree/fident.cpp b/src/modules/m_spanningtree/fident.cpp
index 0744d9bf2..8cd3618db 100644
--- a/src/modules/m_spanningtree/fident.cpp
+++ b/src/modules/m_spanningtree/fident.cpp
@@ -25,7 +25,7 @@ bool TreeSocket::ChangeIdent(const std::string &prefix, parameterlist &params)
{
if (params.size() < 1)
return true;
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
u->ChangeIdent(params[0].c_str());
diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp
index 2c3606db1..7f11f40dd 100644
--- a/src/modules/m_spanningtree/fjoin.cpp
+++ b/src/modules/m_spanningtree/fjoin.cpp
@@ -59,7 +59,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist &params)
time_t TS = atoi(params[1].c_str()); /* Timestamp given to us for remote side */
irc::tokenstream users((params.size() > 3) ? params[params.size() - 1] : ""); /* users from the user list */
bool apply_other_sides_modes = true; /* True if we are accepting the other side's modes */
- Channel* chan = this->ServerInstance->FindChan(channel); /* The channel we're sending joins to */
+ Channel* chan = ServerInstance->FindChan(channel); /* The channel we're sending joins to */
bool created = !chan; /* True if the channel doesnt exist here yet */
std::string item; /* One item in the list of nicks */
@@ -123,7 +123,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist &params)
modelist.push_back(params[idx]);
}
- this->ServerInstance->SendMode(modelist, Utils->ServerUser);
+ ServerInstance->SendMode(modelist, Utils->ServerUser);
}
/* Now, process every 'modes,nick' pair */
@@ -156,7 +156,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist &params)
usr++;
/* Check the user actually exists */
- who = this->ServerInstance->FindUUID(usr);
+ who = ServerInstance->FindUUID(usr);
if (who)
{
/* Check that the user's 'direction' is correct */
@@ -168,7 +168,7 @@ bool TreeSocket::ForceJoin(const std::string &source, parameterlist &params)
for (std::string::iterator x = modes.begin(); x != modes.end(); ++x)
modestack.Push(*x, who->nick);
- Channel::JoinUser(this->ServerInstance, who, channel.c_str(), true, "", route_back_again->bursting, TS);
+ Channel::JoinUser(ServerInstance, who, channel.c_str(), true, "", route_back_again->bursting, TS);
}
else
{
diff --git a/src/modules/m_spanningtree/fmode.cpp b/src/modules/m_spanningtree/fmode.cpp
index 3421f8045..3bca098d6 100644
--- a/src/modules/m_spanningtree/fmode.cpp
+++ b/src/modules/m_spanningtree/fmode.cpp
@@ -34,7 +34,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist &params)
std::string sourceserv;
/* Are we dealing with an FMODE from a user, or from a server? */
- User* who = this->ServerInstance->FindNick(source);
+ User* who = ServerInstance->FindNick(source);
if (who)
{
/* FMODE from a user, set sourceserv to the users server name */
@@ -66,7 +66,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist &params)
}
/* Extract the TS value of the object, either User or Channel */
- User* dst = this->ServerInstance->FindNick(params[0]);
+ User* dst = ServerInstance->FindNick(params[0]);
Channel* chan = NULL;
time_t ourTS = 0;
@@ -76,7 +76,7 @@ bool TreeSocket::ForceMode(const std::string &source, parameterlist &params)
}
else
{
- chan = this->ServerInstance->FindChan(params[0]);
+ chan = ServerInstance->FindChan(params[0]);
if (chan)
{
ourTS = chan->age;
diff --git a/src/modules/m_spanningtree/fname.cpp b/src/modules/m_spanningtree/fname.cpp
index a83591a4f..cc7625f12 100644
--- a/src/modules/m_spanningtree/fname.cpp
+++ b/src/modules/m_spanningtree/fname.cpp
@@ -25,7 +25,7 @@ bool TreeSocket::ChangeName(const std::string &prefix, parameterlist &params)
{
if (params.size() < 1)
return true;
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
u->ChangeName(params[0].c_str());
diff --git a/src/modules/m_spanningtree/ftopic.cpp b/src/modules/m_spanningtree/ftopic.cpp
index 34e97dd11..5a6656e3e 100644
--- a/src/modules/m_spanningtree/ftopic.cpp
+++ b/src/modules/m_spanningtree/ftopic.cpp
@@ -27,14 +27,14 @@ bool TreeSocket::ForceTopic(const std::string &source, parameterlist &params)
if (params.size() != 4)
return true;
time_t ts = atoi(params[1].c_str());
- Channel* c = this->ServerInstance->FindChan(params[0]);
+ Channel* c = ServerInstance->FindChan(params[0]);
if (c)
{
if ((ts >= c->topicset) || (c->topic.empty()))
{
if (c->topic != params[3])
{
- User* user = this->ServerInstance->FindNick(source);
+ User* user = ServerInstance->FindNick(source);
// Update topic only when it differs from current topic
c->topic.assign(params[3], 0, ServerInstance->Config->Limits.MaxTopic);
if (!user)
diff --git a/src/modules/m_spanningtree/handshaketimer.cpp b/src/modules/m_spanningtree/handshaketimer.cpp
index 56f34283b..814aa122c 100644
--- a/src/modules/m_spanningtree/handshaketimer.cpp
+++ b/src/modules/m_spanningtree/handshaketimer.cpp
@@ -37,15 +37,15 @@ HandshakeTimer::~HandshakeTimer()
void HandshakeTimer::Tick(time_t TIME)
{
- if (!sock->GetHook())
+ if (!sock->GetIOHook())
{
CancelRepeat();
sock->SendCapabilities(1);
}
- else if (BufferedSocketHSCompleteRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send())
+ else if (BufferedSocketHSCompleteRequest(sock, Utils->Creator, sock->GetIOHook()).Send())
{
CancelRepeat();
- BufferedSocketAttachCertRequest(sock, (Module*)Utils->Creator, sock->GetHook()).Send();
+ BufferedSocketAttachCertRequest(sock, Utils->Creator, sock->GetIOHook()).Send();
sock->SendCapabilities(1);
}
// otherwise, try again later
diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp
index cc1b33f23..b7cddc47a 100644
--- a/src/modules/m_spanningtree/hmac.cpp
+++ b/src/modules/m_spanningtree/hmac.cpp
@@ -129,9 +129,9 @@ bool TreeSocket::ComparePass(const Link& link, const std::string &theirs)
this->auth_challenge = !ourchallenge.empty() && !theirchallenge.empty();
std::string fp;
- if (GetHook())
+ if (GetIOHook())
{
- BufferedSocketCertificateRequest req(this, Utils->Creator, GetHook());
+ BufferedSocketCertificateRequest req(this, Utils->Creator, GetIOHook());
req.Send();
if (req.cert)
{
diff --git a/src/modules/m_spanningtree/kill.cpp b/src/modules/m_spanningtree/kill.cpp
index c2026d0bb..e76fc7f3e 100644
--- a/src/modules/m_spanningtree/kill.cpp
+++ b/src/modules/m_spanningtree/kill.cpp
@@ -28,7 +28,7 @@ bool TreeSocket::RemoteKill(const std::string &prefix, parameterlist &params)
if (params.size() != 2)
return true;
- User* who = this->ServerInstance->FindNick(params[0]);
+ User* who = ServerInstance->FindNick(params[0]);
if (who)
{
@@ -46,7 +46,7 @@ bool TreeSocket::RemoteKill(const std::string &prefix, parameterlist &params)
// this shouldn't ever be null, but it doesn't hurt to check
who->Write(":%s KILL %s :%s (%s)", src->GetName().c_str(), who->nick.c_str(), src->GetName().c_str(), reason.c_str());
}
- this->ServerInstance->Users->QuitUser(who, reason);
+ ServerInstance->Users->QuitUser(who, reason);
}
return true;
}
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 1bc3dfe39..230c3109b 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -275,7 +275,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
/* Gave a hook, but it wasnt one we know */
if ((!x->Hook.empty()) && (Utils->hooks.find(x->Hook.c_str()) == Utils->hooks.end()))
return;
- TreeSocket* newsocket = new TreeSocket(Utils, ServerInstance, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, y, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]);
+ TreeSocket* newsocket = new TreeSocket(Utils, x->IPAddr,x->Port, x->Timeout ? x->Timeout : 10,x->Name.c_str(), x->Bind, y, x->Hook.empty() ? NULL : Utils->hooks[x->Hook.c_str()]);
if (newsocket->GetFd() > -1)
{
/* Handled automatically on success */
@@ -283,8 +283,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
else
{
ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",x->Name.c_str(),strerror(errno));
- if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end())
- ServerInstance->SocketCull[newsocket] = newsocket;
+ ServerInstance->GlobalCulls.AddItem(newsocket);
Utils->DoFailOver(y);
}
}
diff --git a/src/modules/m_spanningtree/metadata.cpp b/src/modules/m_spanningtree/metadata.cpp
index 40a98d93b..135970a4a 100644
--- a/src/modules/m_spanningtree/metadata.cpp
+++ b/src/modules/m_spanningtree/metadata.cpp
@@ -33,26 +33,26 @@ bool TreeSocket::MetaData(const std::string &prefix, parameterlist &params)
{
if (params[0] == "*")
{
- FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],params[2]));
+ FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(NULL,params[1],params[2]));
}
else if (*(params[0].c_str()) == '#')
{
- Channel* c = this->ServerInstance->FindChan(params[0]);
+ Channel* c = ServerInstance->FindChan(params[0]);
if (c)
{
if (item)
item->unserialize(FORMAT_NETWORK, c, params[2]);
- FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],params[2]));
+ FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(c,params[1],params[2]));
}
}
else if (*(params[0].c_str()) != '#')
{
- User* u = this->ServerInstance->FindNick(params[0]);
+ User* u = ServerInstance->FindNick(params[0]);
if (u)
{
if (item)
item->unserialize(FORMAT_NETWORK, u, params[2]);
- FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],params[2]));
+ FOREACH_MOD_I(ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(u,params[1],params[2]));
}
}
}
diff --git a/src/modules/m_spanningtree/modules.cpp b/src/modules/m_spanningtree/modules.cpp
index 6c9132794..7a20a98ff 100644
--- a/src/modules/m_spanningtree/modules.cpp
+++ b/src/modules/m_spanningtree/modules.cpp
@@ -26,7 +26,7 @@ bool TreeSocket::Modules(const std::string &prefix, parameterlist &params)
if (params.empty())
return true;
- if (!InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
+ if (!InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
{
/* Pass it on, not for us */
Utils->DoOneToOne(prefix, "MODULES", params, params[0]);
@@ -38,7 +38,7 @@ bool TreeSocket::Modules(const std::string &prefix, parameterlist &params)
par.push_back(prefix);
par.push_back("");
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (!source)
return true;
diff --git a/src/modules/m_spanningtree/motd.cpp b/src/modules/m_spanningtree/motd.cpp
index e42c53152..0c775d644 100644
--- a/src/modules/m_spanningtree/motd.cpp
+++ b/src/modules/m_spanningtree/motd.cpp
@@ -27,11 +27,11 @@ bool TreeSocket::Motd(const std::string &prefix, parameterlist &params)
{
if (params.size() > 0)
{
- if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
+ if (InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
{
/* It's for our server */
string_list results;
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
{
@@ -42,27 +42,27 @@ bool TreeSocket::Motd(const std::string &prefix, parameterlist &params)
if (!ServerInstance->Config->MOTD.size())
{
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing.";
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
return true;
}
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day";
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
for (unsigned int i = 0; i < ServerInstance->Config->MOTD.size(); i++)
{
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 372 "+source->nick+" :- "+ServerInstance->Config->MOTD[i];
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
}
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day.";
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
}
}
else
{
/* Pass it on */
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
Utils->DoOneToOne(prefix, "MOTD", params, params[0]);
}
diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp
index ada10e6a1..3cfad9b63 100644
--- a/src/modules/m_spanningtree/netburst.cpp
+++ b/src/modules/m_spanningtree/netburst.cpp
@@ -30,16 +30,16 @@
void TreeSocket::DoBurst(TreeServer* s)
{
std::string name = s->GetName();
- std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time());
- std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST";
- this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).",
+ std::string burst = ":" + ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time());
+ std::string endburst = ":" + ServerInstance->Config->GetSID() + " ENDBURST";
+ ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).",
name.c_str(),
this->auth_fingerprint ? "SSL Fingerprint and " : "",
this->auth_challenge ? "challenge-response" : "plaintext password");
this->CleanNegotiationInfo();
this->WriteLine(burst);
/* send our version string */
- this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString());
+ this->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" VERSION :"+ServerInstance->GetVersionString());
/* Send server tree */
this->SendServers(Utils->TreeRoot,s,1);
/* Send users and their oper status */
@@ -47,9 +47,9 @@ void TreeSocket::DoBurst(TreeServer* s)
/* Send everything else (channel modes, xlines etc) */
this->SendChannelModes(s);
this->SendXLines(s);
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this));
+ FOREACH_MOD_I(ServerInstance,I_OnSyncNetwork,OnSyncNetwork(Utils->Creator,(void*)this));
this->WriteLine(endburst);
- this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2.");
+ ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2.");
}
/** Recursively send the server tree with distances as hops.
@@ -91,7 +91,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c)
size_t curlen, headlen;
curlen = headlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu +%s :",
- this->ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true));
+ ServerInstance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true));
int numusers = 0;
char* ptr = list + curlen;
bool looped_once = false;
@@ -103,7 +103,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c)
for (UserMembCIter i = ulist->begin(); i != ulist->end(); i++)
{
size_t ptrlen = 0;
- std::string modestr = this->ServerInstance->Modes->ModeString(i->first, c, false);
+ std::string modestr = ServerInstance->Modes->ModeString(i->first, c, false);
if ((curlen + modestr.length() + i->first->uuid.length() + 4) > 480)
{
@@ -150,7 +150,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c)
if ((params.length() >= ServerInstance->Config->Limits.MaxModes) || (currsize > 350))
{
/* Wrap at MAXMODES */
- buffer.append(":").append(this->ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
+ buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n");
modes.clear();
params.clear();
linesize = 1;
@@ -159,7 +159,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c)
/* Only send these if there are any */
if (!modes.empty())
- buffer.append(":").append(this->ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
+ buffer.append(":").append(ServerInstance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params);
this->WriteLine(buffer);
}
@@ -168,7 +168,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c)
void TreeSocket::SendXLines(TreeServer* Current)
{
char data[MAXBUF];
- std::string n = this->ServerInstance->Config->GetSID();
+ std::string n = ServerInstance->Config->GetSID();
const char* sn = n.c_str();
std::vector<std::string> types = ServerInstance->XLines->GetAllTypes();
@@ -209,9 +209,9 @@ void TreeSocket::SendChannelModes(TreeServer* Current)
{
char data[MAXBUF];
std::deque<std::string> list;
- std::string n = this->ServerInstance->Config->GetSID();
+ std::string n = ServerInstance->Config->GetSID();
const char* sn = n.c_str();
- for (chan_hash::iterator c = this->ServerInstance->chanlist->begin(); c != this->ServerInstance->chanlist->end(); c++)
+ for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
{
SendFJoins(Current, c->second);
if (!c->second->topic.empty())
@@ -230,7 +230,7 @@ void TreeSocket::SendChannelModes(TreeServer* Current)
Utils->Creator->ProtoSendMetaData(this, c->second, i->first, value);
}
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this));
+ FOREACH_MOD_I(ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,Utils->Creator,this));
}
}
@@ -239,7 +239,7 @@ void TreeSocket::SendUsers(TreeServer* Current)
{
char data[MAXBUF];
std::string dataline;
- for (user_hash::iterator u = this->ServerInstance->Users->clientlist->begin(); u != this->ServerInstance->Users->clientlist->end(); u++)
+ for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
{
if (u->second->registered == REG_ALL)
{
@@ -281,7 +281,7 @@ void TreeSocket::SendUsers(TreeServer* Current)
Utils->Creator->ProtoSendMetaData(this, u->second, i->first, value);
}
- FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,Utils->Creator,this));
+ FOREACH_MOD_I(ServerInstance,I_OnSyncUser,OnSyncUser(u->second,Utils->Creator,this));
}
}
}
diff --git a/src/modules/m_spanningtree/nickcollide.cpp b/src/modules/m_spanningtree/nickcollide.cpp
index a723c114f..4481ba35e 100644
--- a/src/modules/m_spanningtree/nickcollide.cpp
+++ b/src/modules/m_spanningtree/nickcollide.cpp
@@ -114,7 +114,7 @@ int TreeSocket::DoCollision(User *u, time_t remotets, const std::string &remotei
}
if (bChangeRemote)
{
- User *remote = this->ServerInstance->FindUUID(remoteuid);
+ User *remote = ServerInstance->FindUUID(remoteuid);
/*
* remote side needs to change. If this happens, we will modify
* the UID or halt the propagation of the nick change command,
diff --git a/src/modules/m_spanningtree/operquit.cpp b/src/modules/m_spanningtree/operquit.cpp
index 5cdee3bc6..9128baa0f 100644
--- a/src/modules/m_spanningtree/operquit.cpp
+++ b/src/modules/m_spanningtree/operquit.cpp
@@ -26,7 +26,7 @@ bool TreeSocket::OperQuit(const std::string &prefix, parameterlist &params)
if (params.size() < 1)
return true;
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
diff --git a/src/modules/m_spanningtree/opertype.cpp b/src/modules/m_spanningtree/opertype.cpp
index c1105aa71..a1ad88007 100644
--- a/src/modules/m_spanningtree/opertype.cpp
+++ b/src/modules/m_spanningtree/opertype.cpp
@@ -29,11 +29,11 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist &params)
if (params.size() != 1)
return true;
std::string opertype = params[0];
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
if (!IS_OPER(u))
- this->ServerInstance->Users->all_opers.push_back(u);
+ ServerInstance->Users->all_opers.push_back(u);
u->modes[UM_OPERATOR] = 1;
u->oper.assign(opertype, 0, 512);
Utils->DoOneToAllButSender(u->uuid, "OPERTYPE", params, u->server);
@@ -49,7 +49,7 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist &params)
*/
if (
remoteserver->bursting ||
- this->ServerInstance->SilentULine(this->ServerInstance->FindServerNamePtr(u->server))
+ ServerInstance->SilentULine(ServerInstance->FindServerNamePtr(u->server))
)
{
dosend = false;
@@ -57,7 +57,7 @@ bool TreeSocket::OperType(const std::string &prefix, parameterlist &params)
}
if (dosend)
- this->ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server, u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str()));
+ ServerInstance->SNO->WriteToSnoMask('O',"From %s: User %s (%s@%s) is now an IRC operator of type %s",u->server, u->nick.c_str(),u->ident.c_str(), u->host.c_str(), irc::Spacify(opertype.c_str()));
}
return true;
}
diff --git a/src/modules/m_spanningtree/override_stats.cpp b/src/modules/m_spanningtree/override_stats.cpp
index 9986763d9..5d0239f84 100644
--- a/src/modules/m_spanningtree/override_stats.cpp
+++ b/src/modules/m_spanningtree/override_stats.cpp
@@ -78,8 +78,8 @@ ModResult ModuleSpanningTree::OnStats(char statschar, User* user, string_list &r
ip = "*";
std::string transport("plaintext");
- if (Utils->Bindings[i]->GetIOHook())
- transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->GetIOHook()).Send();
+ if (Utils->Bindings[i]->Hook)
+ transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->Hook).Send();
results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->GetPort())+
" (server, " + transport + ")");
diff --git a/src/modules/m_spanningtree/ping.cpp b/src/modules/m_spanningtree/ping.cpp
index 1318b60a0..c3467c984 100644
--- a/src/modules/m_spanningtree/ping.cpp
+++ b/src/modules/m_spanningtree/ping.cpp
@@ -31,13 +31,13 @@ bool TreeSocket::LocalPing(const std::string &prefix, parameterlist &params)
if (params.size() == 1)
{
std::string stufftobounce = params[0];
- this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" PONG "+stufftobounce);
+ this->WriteLine(std::string(":")+ServerInstance->Config->GetSID()+" PONG "+stufftobounce);
return true;
}
else
{
std::string forwardto = params[1];
- if (forwardto == this->ServerInstance->Config->ServerName || forwardto == this->ServerInstance->Config->GetSID())
+ if (forwardto == ServerInstance->Config->ServerName || forwardto == ServerInstance->Config->GetSID())
{
// this is a ping for us, send back PONG to the requesting server
params[1] = params[0];
diff --git a/src/modules/m_spanningtree/pong.cpp b/src/modules/m_spanningtree/pong.cpp
index b551ef6d2..274641897 100644
--- a/src/modules/m_spanningtree/pong.cpp
+++ b/src/modules/m_spanningtree/pong.cpp
@@ -52,7 +52,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist &params)
* dump the PONG reply back to their fd. If its a server, do nowt.
* Services might want to send these s->s, but we dont need to yet.
*/
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
u->WriteServ("PONG %s %s",params[0].c_str(),params[1].c_str());
diff --git a/src/modules/m_spanningtree/push.cpp b/src/modules/m_spanningtree/push.cpp
index 88c6b55bd..778c2291c 100644
--- a/src/modules/m_spanningtree/push.cpp
+++ b/src/modules/m_spanningtree/push.cpp
@@ -28,7 +28,7 @@ bool TreeSocket::Push(const std::string &prefix, parameterlist &params)
{
if (params.size() < 2)
return true;
- User* u = this->ServerInstance->FindNick(params[0]);
+ User* u = ServerInstance->FindNick(params[0]);
if (!u)
return true;
if (IS_LOCAL(u))
diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp
index 73e67c4f7..c7c49b348 100644
--- a/src/modules/m_spanningtree/resolvers.cpp
+++ b/src/modules/m_spanningtree/resolvers.cpp
@@ -49,7 +49,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in
if ((!MyLink.Hook.empty()) && (Utils->hooks.find(MyLink.Hook.c_str()) == Utils->hooks.end()))
return;
- TreeSocket* newsocket = new TreeSocket(this->Utils, ServerInstance, result,MyLink.Port,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str(),
+ TreeSocket* newsocket = new TreeSocket(this->Utils, result,MyLink.Port,MyLink.Timeout ? MyLink.Timeout : 10,MyLink.Name.c_str(),
MyLink.Bind, myautoconnect, MyLink.Hook.empty() ? NULL : Utils->hooks[MyLink.Hook.c_str()]);
if (newsocket->GetFd() > -1)
{
@@ -59,8 +59,7 @@ void ServernameResolver::OnLookupComplete(const std::string &result, unsigned in
{
/* Something barfed, show the opers */
ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Error connecting \002%s\002: %s.",MyLink.Name.c_str(),strerror(errno));
- if (ServerInstance->SocketCull.find(newsocket) == ServerInstance->SocketCull.end())
- ServerInstance->SocketCull[newsocket] = newsocket;
+ ServerInstance->GlobalCulls.AddItem(newsocket);
Utils->DoFailOver(myautoconnect);
}
}
diff --git a/src/modules/m_spanningtree/save.cpp b/src/modules/m_spanningtree/save.cpp
index 9969fdca7..cfa8dc794 100644
--- a/src/modules/m_spanningtree/save.cpp
+++ b/src/modules/m_spanningtree/save.cpp
@@ -32,7 +32,7 @@ bool TreeSocket::ForceNick(const std::string &prefix, parameterlist &params)
if (params.size() < 2)
return true;
- User* u = this->ServerInstance->FindNick(params[0]);
+ User* u = ServerInstance->FindNick(params[0]);
time_t ts = atol(params[1].c_str());
if (u && u->age == ts)
@@ -41,7 +41,7 @@ bool TreeSocket::ForceNick(const std::string &prefix, parameterlist &params)
if (!u->ForceNickChange(u->uuid.c_str()))
{
- this->ServerInstance->Users->QuitUser(u, "Nickname collision");
+ ServerInstance->Users->QuitUser(u, "Nickname collision");
}
}
diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp
index c275f3490..025675642 100644
--- a/src/modules/m_spanningtree/server.cpp
+++ b/src/modules/m_spanningtree/server.cpp
@@ -49,7 +49,7 @@ bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist &params)
this->SendError("Protocol error - Introduced remote server from unknown server "+ParentOfThis->GetName());
return false;
}
- if (!this->ServerInstance->IsSID(sid))
+ if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
@@ -58,26 +58,26 @@ bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist &params)
if (CheckDupe)
{
this->SendError("Server "+servername+" already exists!");
- this->ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName());
+ ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName());
return false;
}
CheckDupe = Utils->FindServer(sid);
if (CheckDupe)
{
this->SendError("Server ID "+sid+" already exists! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
- this->ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName());
+ ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName());
return false;
}
Link* lnk = Utils->FindLink(servername);
- TreeServer *Node = new TreeServer(this->Utils, this->ServerInstance, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false);
+ TreeServer *Node = new TreeServer(this->Utils, ServerInstance, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false);
ParentOfThis->AddChild(Node);
params[4] = ":" + params[4];
Utils->DoOneToAllButSender(prefix,"SERVER",params,prefix);
- this->ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")");
+ ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")");
return true;
}
@@ -110,11 +110,11 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
if (hops)
{
this->SendError("Server too far away for authentication");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication");
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication");
return false;
}
- if (!this->ServerInstance->IsSID(sid))
+ if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
@@ -127,7 +127,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
if (!ComparePass(*x, password))
{
- this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
}
@@ -135,14 +135,14 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
if (CheckDupe)
{
this->SendError("Server "+sname+" already exists on server "+CheckDupe->GetParent()->GetName()+"!");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName());
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName());
return false;
}
CheckDupe = Utils->FindServer(sid);
if (CheckDupe)
{
this->SendError("Server ID "+sid+" already exists on the network! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link.");
+ ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link.");
return false;
}
@@ -158,7 +158,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
Utils->timeoutlist.erase(this);
- TreeServer *Node = new TreeServer(this->Utils, this->ServerInstance, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
+ TreeServer *Node = new TreeServer(this->Utils, ServerInstance, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
Utils->TreeRoot->AddChild(Node);
params[4] = ":" + params[4];
@@ -173,7 +173,7 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist &params)
}
this->SendError("Invalid credentials (check the other server's linking snomask for more information)");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
return false;
}
@@ -205,11 +205,11 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
if (hops)
{
this->SendError("Server too far away for authentication");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication");
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication");
return false;
}
- if (!this->ServerInstance->IsSID(sid))
+ if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
@@ -222,7 +222,7 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
if (!ComparePass(*x, password))
{
- this->ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
}
@@ -231,7 +231,7 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
if (CheckDupe)
{
this->SendError("Server "+sname+" already exists on server "+CheckDupe->GetParent()->GetName()+"!");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName());
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+CheckDupe->GetParent()->GetName());
return false;
}
@@ -242,30 +242,30 @@ bool TreeSocket::Inbound_Server(parameterlist &params)
if (CheckDupe)
{
this->SendError("Server ID "+CheckDupe->GetID()+" already exists on server "+CheckDupe->GetName()+"! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server ID '"+CheckDupe->GetID()+
"' already exists on server "+CheckDupe->GetName());
return false;
}
- this->ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection from \002"+sname+"\002["+(x->HiddenFromStats ? "<hidden>" : this->GetIP())+"] ("+description+")");
- if (this->Hook)
+ ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection from \002"+sname+"\002["+(x->HiddenFromStats ? "<hidden>" : this->IP)+"] ("+description+")");
+ if (this->GetIOHook())
{
- std::string name = BufferedSocketNameRequest((Module*)Utils->Creator, this->Hook).Send();
- this->ServerInstance->SNO->WriteToSnoMask('l',"Connection from \2"+sname+"\2["+(x->HiddenFromStats ? "<hidden>" : this->GetIP())+"] using transport \2"+name+"\2");
+ std::string name = BufferedSocketNameRequest(Utils->Creator, this->GetIOHook()).Send();
+ ServerInstance->SNO->WriteToSnoMask('l',"Connection from \2"+sname+"\2["+(x->HiddenFromStats ? "<hidden>" : this->IP)+"] using transport \2"+name+"\2");
}
// this is good. Send our details: Our server name and description and hopcount of 0,
// along with the sendpass from this block.
this->SendCapabilities(2);
- this->WriteLine(std::string("SERVER ")+this->ServerInstance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+ServerInstance->Config->GetSID()+" :"+this->ServerInstance->Config->ServerDesc);
+ this->WriteLine(std::string("SERVER ")+ServerInstance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc);
// move to the next state, we are now waiting for THEM.
this->LinkState = WAIT_AUTH_2;
return true;
}
this->SendError("Invalid credentials");
- this->ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
+ ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
return false;
}
diff --git a/src/modules/m_spanningtree/stats.cpp b/src/modules/m_spanningtree/stats.cpp
index d67c5a3af..71f12d50b 100644
--- a/src/modules/m_spanningtree/stats.cpp
+++ b/src/modules/m_spanningtree/stats.cpp
@@ -32,11 +32,11 @@ bool TreeSocket::Stats(const std::string &prefix, parameterlist &params)
*/
if (params.size() > 1)
{
- if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[1]))
+ if (InspIRCd::Match(ServerInstance->Config->ServerName, params[1]))
{
/* It's for our server */
string_list results;
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
{
parameterlist par;
@@ -46,14 +46,14 @@ bool TreeSocket::Stats(const std::string &prefix, parameterlist &params)
for (size_t i = 0; i < results.size(); i++)
{
par[1] = "::" + results[i];
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH",par, source->server);
}
}
}
else
{
/* Pass it on */
- User* source = this->ServerInstance->FindNick(prefix);
+ User* source = ServerInstance->FindNick(prefix);
if (source)
Utils->DoOneToOne(source->uuid, "STATS", params, params[1]);
}
diff --git a/src/modules/m_spanningtree/svsjoin.cpp b/src/modules/m_spanningtree/svsjoin.cpp
index b6246e2f4..1664190f8 100644
--- a/src/modules/m_spanningtree/svsjoin.cpp
+++ b/src/modules/m_spanningtree/svsjoin.cpp
@@ -29,13 +29,13 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, parameterlist &params)
if (params.size() < 2)
return true;
- User* u = this->ServerInstance->FindNick(params[0]);
+ User* u = ServerInstance->FindNick(params[0]);
if (u)
{
/* only join if it's local, otherwise just pass it on! */
if (IS_LOCAL(u))
- Channel::JoinUser(this->ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time());
+ Channel::JoinUser(ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time());
Utils->DoOneToAllButSender(prefix,"SVSJOIN",params,prefix);
}
return true;
diff --git a/src/modules/m_spanningtree/svsnick.cpp b/src/modules/m_spanningtree/svsnick.cpp
index 3af6961d0..7a723a36d 100644
--- a/src/modules/m_spanningtree/svsnick.cpp
+++ b/src/modules/m_spanningtree/svsnick.cpp
@@ -32,7 +32,7 @@ bool TreeSocket::SVSNick(const std::string &prefix, parameterlist &params)
if (params.size() < 3)
return true;
- User* u = this->ServerInstance->FindNick(params[0]);
+ User* u = ServerInstance->FindNick(params[0]);
if (u)
{
@@ -48,7 +48,7 @@ bool TreeSocket::SVSNick(const std::string &prefix, parameterlist &params)
/* buh. UID them */
if (!u->ForceNickChange(u->uuid.c_str()))
{
- this->ServerInstance->Users->QuitUser(u, "Nickname collision");
+ ServerInstance->Users->QuitUser(u, "Nickname collision");
return true;
}
}
diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp
index 83e329b4e..1e26c90d9 100644
--- a/src/modules/m_spanningtree/svspart.cpp
+++ b/src/modules/m_spanningtree/svspart.cpp
@@ -34,8 +34,8 @@ bool TreeSocket::ServicePart(const std::string &prefix, parameterlist &params)
if (params.size() == 3)
reason = params[2];
- User* u = this->ServerInstance->FindNick(params[0]);
- Channel* c = this->ServerInstance->FindChan(params[1]);
+ User* u = ServerInstance->FindNick(params[0]);
+ Channel* c = ServerInstance->FindChan(params[1]);
if (u)
{
diff --git a/src/modules/m_spanningtree/time.cpp b/src/modules/m_spanningtree/time.cpp
index 82a7fe62e..6fdcf8b53 100644
--- a/src/modules/m_spanningtree/time.cpp
+++ b/src/modules/m_spanningtree/time.cpp
@@ -31,20 +31,20 @@ bool TreeSocket::Time(const std::string &prefix, parameterlist &params)
if (params.size() == 2)
{
// someone querying our time?
- if (this->ServerInstance->Config->ServerName == params[0] || this->ServerInstance->Config->GetSID() == params[0])
+ if (ServerInstance->Config->ServerName == params[0] || ServerInstance->Config->GetSID() == params[0])
{
- User* u = this->ServerInstance->FindNick(params[1]);
+ User* u = ServerInstance->FindNick(params[1]);
if (u)
{
params.push_back(ConvToStr(ServerInstance->Time()));
params[0] = prefix;
- Utils->DoOneToOne(this->ServerInstance->Config->GetSID(),"TIME",params,params[0]);
+ Utils->DoOneToOne(ServerInstance->Config->GetSID(),"TIME",params,params[0]);
}
}
else
{
// not us, pass it on
- User* u = this->ServerInstance->FindNick(params[1]);
+ User* u = ServerInstance->FindNick(params[1]);
if (u)
Utils->DoOneToOne(prefix,"TIME",params,params[0]);
}
@@ -52,7 +52,7 @@ bool TreeSocket::Time(const std::string &prefix, parameterlist &params)
else if (params.size() == 3)
{
// a response to a previous TIME
- User* u = this->ServerInstance->FindNick(params[1]);
+ User* u = ServerInstance->FindNick(params[1]);
if ((u) && (IS_LOCAL(u)))
{
std::string sourceserv = Utils->FindServer(prefix)->GetName();
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index a26e89f85..3c9484981 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -71,7 +71,6 @@ class TreeSocket : public BufferedSocket
{
SpanningTreeUtilities* Utils; /* Utility class */
std::string myhost; /* Canonical hostname */
- std::string in_buffer; /* Input buffer */
ServerState LinkState; /* Link state */
std::string InboundServerName; /* Server name sent to us by other side */
std::string InboundDescription; /* Server description (GECOS) sent to us by the other side */
@@ -80,10 +79,10 @@ class TreeSocket : public BufferedSocket
int num_lost_servers; /* Servers lost in split */
time_t NextPing; /* Time when we are due to ping this server */
bool LastPingWasGood; /* Responded to last ping we sent? */
+ std::string IP;
std::string ModuleList; /* Required module list of other server from CAPAB */
std::string OptModuleList; /* Optional module list of other server from CAPAB */
std::map<std::string,std::string> CapKeys; /* CAPAB keys from other server */
- Module* Hook; /* I/O hooking module that we're attached to for this socket */
std::string ourchallenge; /* Challenge sent for challenge/response */
std::string theirchallenge; /* Challenge recv for challenge/response */
std::string OutboundPass; /* Outbound password */
@@ -101,13 +100,13 @@ class TreeSocket : public BufferedSocket
* most of the action, and append a few of our own values
* to it.
*/
- TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod = NULL);
+ TreeSocket(SpanningTreeUtilities* Util, std::string host, int port, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod = NULL);
/** When a listening socket gives us a new file descriptor,
* we must associate it with a socket without creating a new
* connection. This constructor is used for this purpose.
*/
- TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod = NULL);
+ TreeSocket(SpanningTreeUtilities* Util, int newfd, char* ip, Autoconnect* myac, Module* HookMod = NULL);
/** Get link state
*/
@@ -137,10 +136,6 @@ class TreeSocket : public BufferedSocket
*/
void CleanNegotiationInfo();
- /** Return the module which we are hooking to for I/O encapsulation
- */
- Module* GetHook();
-
/** Destructor
*/
~TreeSocket();
@@ -160,7 +155,7 @@ class TreeSocket : public BufferedSocket
* to server docs on the inspircd.org site, the other side
* will then send back its own server string.
*/
- virtual bool OnConnected();
+ virtual void OnConnected();
/** Handle socket error event
*/
@@ -171,10 +166,6 @@ class TreeSocket : public BufferedSocket
*/
void SendError(const std::string &errormessage);
- /** Handle socket disconnect event
- */
- virtual int OnDisconnect();
-
/** Recursively send the server tree with distances as hops.
* This is used during network burst to inform the other server
* (and any of ITS servers too) of what servers we know about.
@@ -258,14 +249,9 @@ class TreeSocket : public BufferedSocket
void DoBurst(TreeServer* s);
/** This function is called when we receive data from a remote
- * server. We buffer the data in a std::string (it doesnt stay
- * there for long), reading using BufferedSocket::Read() which can
- * read up to 16 kilobytes in one operation.
- *
- * IF THIS FUNCTION RETURNS FALSE, THE CORE CLOSES AND DELETES
- * THE SOCKET OBJECT FOR US.
+ * server.
*/
- virtual bool OnDataReady();
+ void OnDataReady();
/** Send one or more complete lines down the socket
*/
@@ -404,10 +390,9 @@ class TreeSocket : public BufferedSocket
/** Handle socket timeout from connect()
*/
virtual void OnTimeout();
-
- /** Handle socket close event
+ /** Handle server quit on close
*/
- virtual void OnClose();
+ virtual void Close();
};
/* Used to validate the value lengths of multiple parameters for a command */
diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp
index d59364751..55fbc2c91 100644
--- a/src/modules/m_spanningtree/treesocket1.cpp
+++ b/src/modules/m_spanningtree/treesocket1.cpp
@@ -34,17 +34,18 @@
* most of the action, and append a few of our own values
* to it.
*/
-TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod)
- : BufferedSocket(SI, shost, iport, maxtime, bindto), Utils(Util), Hook(HookMod), myautoconnect(myac)
+TreeSocket::TreeSocket(SpanningTreeUtilities* Util, std::string shost, int iport, unsigned long maxtime, const std::string &ServerName, const std::string &bindto, Autoconnect* myac, Module* HookMod)
+ : Utils(Util), IP(shost), myautoconnect(myac)
{
- age = SI->Time();
+ age = ServerInstance->Time();
myhost = ServerName;
capab_phase = 0;
proto_version = 0;
LinkState = CONNECTING;
+ DoConnect(shost, iport, maxtime, bindto);
Utils->timeoutlist[this] = std::pair<std::string, int>(ServerName, maxtime);
- if (Hook)
- BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
+ if (HookMod)
+ BufferedSocketHookRequest(this, Utils->Creator, HookMod).Send();
hstimer = NULL;
}
@@ -52,18 +53,18 @@ TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, std::string sh
* we must associate it with a socket without creating a new
* connection. This constructor is used for this purpose.
*/
-TreeSocket::TreeSocket(SpanningTreeUtilities* Util, InspIRCd* SI, int newfd, char* ip, Autoconnect* myac, Module* HookMod)
- : BufferedSocket(SI, newfd, ip), Utils(Util), Hook(HookMod), myautoconnect(myac)
+TreeSocket::TreeSocket(SpanningTreeUtilities* Util, int newfd, char* ip, Autoconnect* myac, Module* HookMod)
+ : BufferedSocket(newfd), Utils(Util), IP(ip), myautoconnect(myac)
{
- age = SI->Time();
+ age = ServerInstance->Time();
LinkState = WAIT_AUTH_1;
capab_phase = 0;
proto_version = 0;
/* If we have a transport module hooked to the parent, hook the same module to this
* socket, and set a timer waiting for handshake before we send CAPAB etc.
*/
- if (Hook)
- BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
+ if (HookMod)
+ BufferedSocketHookRequest(this, Utils->Creator, HookMod).Send();
hstimer = new HandshakeTimer(ServerInstance, this, &(Utils->LinkBlocks[0]), this->Utils, 1);
ServerInstance->Timers->AddTimer(hstimer);
@@ -77,11 +78,6 @@ ServerState TreeSocket::GetLinkState()
return this->LinkState;
}
-Module* TreeSocket::GetHook()
-{
- return this->Hook;
-}
-
void TreeSocket::CleanNegotiationInfo()
{
ModuleList.clear();
@@ -94,8 +90,8 @@ void TreeSocket::CleanNegotiationInfo()
TreeSocket::~TreeSocket()
{
- if (Hook)
- BufferedSocketUnhookRequest(this, (Module*)Utils->Creator, Hook).Send();
+ if (GetIOHook())
+ BufferedSocketUnhookRequest(this, Utils->Creator, GetIOHook()).Send();
if (hstimer)
ServerInstance->Timers->DelTimer(hstimer);
Utils->timeoutlist.erase(this);
@@ -107,7 +103,7 @@ TreeSocket::~TreeSocket()
* to server docs on the inspircd.org site, the other side
* will then send back its own server string.
*/
-bool TreeSocket::OnConnected()
+void TreeSocket::OnConnected()
{
if (this->LinkState == CONNECTING)
{
@@ -116,25 +112,17 @@ bool TreeSocket::OnConnected()
{
if (x->Name == this->myhost)
{
- ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] started.", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->GetIP().c_str()));
- if (Hook)
- {
- BufferedSocketHookRequest(this, (Module*)Utils->Creator, Hook).Send();
- ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] using transport \2%s\2", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->GetIP().c_str()),
- x->Hook.c_str());
- }
+ ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] started.", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->IP.c_str()));
this->OutboundPass = x->SendPass;
-
- /* found who we're supposed to be connecting to, send the neccessary gubbins. */
- if (this->GetHook())
+ if (GetIOHook())
{
+ ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2[%s] using transport \2%s\2", myhost.c_str(), (x->HiddenFromStats ? "<hidden>" : this->IP.c_str()), x->Hook.c_str());
hstimer = new HandshakeTimer(ServerInstance, this, &(*x), this->Utils, 1);
ServerInstance->Timers->AddTimer(hstimer);
}
else
this->SendCapabilities(1);
-
- return true;
+ return;
}
}
}
@@ -144,7 +132,6 @@ bool TreeSocket::OnConnected()
* and rather harmless.
*/
ServerInstance->SNO->WriteToSnoMask('l', "Connection to \2%s\2 lost link tag(!)", myhost.c_str());
- return true;
}
void TreeSocket::OnError(BufferedSocketError e)
@@ -174,21 +161,11 @@ void TreeSocket::OnError(BufferedSocketError e)
}
}
-int TreeSocket::OnDisconnect()
-{
- /* For the same reason as above, we don't
- * handle OnDisconnect()
- */
- return true;
-}
-
void TreeSocket::SendError(const std::string &errormessage)
{
/* Display the error locally as well as sending it remotely */
- ServerInstance->SNO->WriteToSnoMask('l', "Sent \2ERROR\2 to %s: %s", (this->InboundServerName.empty() ? this->GetIP().c_str() : this->InboundServerName.c_str()), errormessage.c_str());
- this->WriteLine("ERROR :"+errormessage);
- /* One last attempt to make sure the error reaches its target */
- this->FlushWriteBuffer();
+ ServerInstance->SNO->WriteToSnoMask('l', "Sent \2ERROR\2 to %s: %s", (this->InboundServerName.empty() ? this->IP.c_str() : this->InboundServerName.c_str()), errormessage.c_str());
+ WriteLine("ERROR :"+errormessage);
}
/** This function forces this server to quit, removing this server
@@ -232,12 +209,12 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName());
if (Current->GetParent() == Utils->TreeRoot)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
+ ServerInstance->SNO->WriteToSnoMask('l', "Server \002"+Current->GetName()+"\002 split: "+reason);
LocalSquit = true;
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+Current->GetName()+"\002 split from server \002"+Current->GetParent()->GetName()+"\002 with reason: "+reason);
+ ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+Current->GetName()+"\002 split from server \002"+Current->GetParent()->GetName()+"\002 with reason: "+reason);
}
num_lost_servers = 0;
num_lost_users = 0;
@@ -247,56 +224,41 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason)
Current->GetParent()->DelChild(Current);
delete Current;
if (LocalSquit)
- this->ServerInstance->SNO->WriteToSnoMask('l', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers);
+ ServerInstance->SNO->WriteToSnoMask('l', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers);
else
- this->ServerInstance->SNO->WriteToSnoMask('L', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers);
+ ServerInstance->SNO->WriteToSnoMask('L', "Netsplit complete, lost \002%d\002 users on \002%d\002 servers.", num_lost_users, num_lost_servers);
}
else
ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Squit from unknown server");
}
/** This function is called when we receive data from a remote
- * server. We buffer the data in a std::string (it doesnt stay
- * there for long), reading using BufferedSocket::Read() which can
- * read up to 16 kilobytes in one operation.
- *
- * IF THIS FUNCTION RETURNS FALSE, THE CORE CLOSES AND DELETES
- * THE SOCKET OBJECT FOR US.
+ * server.
*/
-bool TreeSocket::OnDataReady()
+void TreeSocket::OnDataReady()
{
- const char* data = this->Read();
- /* Check that the data read is a valid pointer and it has some content */
- if (data && *data)
+ Utils->Creator->loopCall = true;
+ /* While there is at least one new line in the buffer,
+ * do something useful (we hope!) with it.
+ */
+ while (recvq.find("\n") != std::string::npos)
{
- this->in_buffer.append(data);
- Utils->Creator->loopCall = true;
- /* While there is at least one new line in the buffer,
- * do something useful (we hope!) with it.
+ std::string ret = recvq.substr(0,recvq.find("\n")-1);
+ recvq = recvq.substr(recvq.find("\n")+1,recvq.length()-recvq.find("\n"));
+ /* Use rfind here not find, as theres more
+ * chance of the \r being near the end of the
+ * string, not the start.
*/
- while (in_buffer.find("\n") != std::string::npos)
+ if (ret.find("\r") != std::string::npos)
+ ret = recvq.substr(0,recvq.find("\r")-1);
+ /* Process this one, abort if it
+ * didnt return true.
+ */
+ if (!this->ProcessLine(ret))
{
- std::string ret = in_buffer.substr(0,in_buffer.find("\n")-1);
- in_buffer = in_buffer.substr(in_buffer.find("\n")+1,in_buffer.length()-in_buffer.find("\n"));
- /* Use rfind here not find, as theres more
- * chance of the \r being near the end of the
- * string, not the start.
- */
- if (ret.find("\r") != std::string::npos)
- ret = in_buffer.substr(0,in_buffer.find("\r")-1);
- /* Process this one, abort if it
- * didnt return true.
- */
- if (!this->ProcessLine(ret))
- {
- return false;
- }
+ SetError("ProcessLine returned false");
+ break;
}
- Utils->Creator->loopCall = false;
- return true;
}
- /* EAGAIN returns an empty but non-NULL string, so this
- * evaluates to TRUE for EAGAIN but to FALSE for EOF.
- */
- return (data && !*data);
+ Utils->Creator->loopCall = false;
}
diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp
index 793802781..cf537f05b 100644
--- a/src/modules/m_spanningtree/treesocket2.cpp
+++ b/src/modules/m_spanningtree/treesocket2.cpp
@@ -32,7 +32,7 @@ bool TreeSocket::Error(parameterlist &params)
{
if (params.size() < 1)
return false;
- this->ServerInstance->SNO->WriteToSnoMask('l',"ERROR from %s: %s",(!InboundServerName.empty() ? InboundServerName.c_str() : myhost.c_str()),params[0].c_str());
+ ServerInstance->SNO->WriteToSnoMask('l',"ERROR from %s: %s",(!InboundServerName.empty() ? InboundServerName.c_str() : myhost.c_str()),params[0].c_str());
/* we will return false to cause the socket to close. */
return false;
}
@@ -126,9 +126,7 @@ bool TreeSocket::ProcessLine(std::string &line)
}
else
{
- // XXX ...wtf.
- irc::string error = "Invalid command in negotiation phase: " + command;
- this->SendError(assign(error));
+ this->SendError(std::string("Invalid command in negotiation phase: ") + command.c_str());
return false;
}
break;
@@ -171,7 +169,7 @@ bool TreeSocket::ProcessLine(std::string &line)
Link* lnk = Utils->FindLink(InboundServerName);
- Node = new TreeServer(this->Utils, this->ServerInstance, InboundServerName, InboundDescription, InboundSID, Utils->TreeRoot, this, lnk ? lnk->Hidden : false);
+ Node = new TreeServer(this->Utils, ServerInstance, InboundServerName, InboundDescription, InboundSID, Utils->TreeRoot, this, lnk ? lnk->Hidden : false);
Utils->TreeRoot->AddChild(Node);
parameterlist sparams;
@@ -242,7 +240,7 @@ bool TreeSocket::ProcessLine(std::string &line)
*/
std::string direction = prefix;
- User *t = this->ServerInstance->FindUUID(prefix);
+ User *t = ServerInstance->FindUUID(prefix);
if (t)
{
/* Find UID */
@@ -316,7 +314,7 @@ bool TreeSocket::ProcessLine(std::string &line)
}
else if ((command == "NOTICE" || command == "PRIVMSG") && (Utils->IsServer(prefix)))
{
- return this->ServerMessage(assign(command), prefix, params, sourceserv);
+ return ServerMessage(assign(command), prefix, params, sourceserv);
}
else if (command == "STATS")
{
@@ -487,7 +485,7 @@ bool TreeSocket::ProcessLine(std::string &line)
// Set prefix server as bursting
if (!ServerSource)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str()));
+ ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got BURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str()));
return false;
}
@@ -498,7 +496,7 @@ bool TreeSocket::ProcessLine(std::string &line)
{
if (!ServerSource)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str()));
+ ServerInstance->SNO->WriteToSnoMask('l', "WTF: Got ENDBURST from a nonexistant server(?): %s", (ServerSource ? ServerSource->GetName().c_str() : prefix.c_str()));
return false;
}
@@ -515,7 +513,7 @@ bool TreeSocket::ProcessLine(std::string &line)
* Not a special s2s command. Emulate the user doing it.
* This saves us having a huge ugly command parser again.
*/
- User* who = this->ServerInstance->FindUUID(prefix);
+ User* who = ServerInstance->FindUUID(prefix);
if (ServerSource)
{
@@ -546,7 +544,7 @@ bool TreeSocket::ProcessLine(std::string &line)
* On nick messages, check that the nick doesnt already exist here.
* If it does, perform collision logic.
*/
- User* x = this->ServerInstance->FindNickOnly(params[0]);
+ User* x = ServerInstance->FindNickOnly(params[0]);
if ((x) && (x != who))
{
int collideret = 0;
@@ -564,7 +562,7 @@ bool TreeSocket::ProcessLine(std::string &line)
}
}
- switch (this->ServerInstance->CallCommandHandler(command.c_str(), params, who))
+ switch (ServerInstance->CallCommandHandler(command.c_str(), params, who))
{
case CMD_INVALID:
/*
@@ -607,13 +605,15 @@ void TreeSocket::OnTimeout()
{
if (this->LinkState == CONNECTING)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Connection to \002%s\002 timed out.", myhost.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Connection to \002%s\002 timed out.", myhost.c_str());
Utils->DoFailOver(myautoconnect);
}
}
-void TreeSocket::OnClose()
+void TreeSocket::Close()
{
+ this->BufferedSocket::Close();
+
// Test fix for big fuckup
if (this->LinkState != CONNECTED)
return;
@@ -634,10 +634,10 @@ void TreeSocket::OnClose()
if (!quitserver.empty())
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' failed.",quitserver.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' failed.",quitserver.c_str());
time_t server_uptime = ServerInstance->Time() - this->age;
if (server_uptime)
- this->ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' was established for %s", quitserver.c_str(), Utils->Creator->TimeToStr(server_uptime).c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "Connection to '\2%s\2' was established for %s", quitserver.c_str(), Utils->Creator->TimeToStr(server_uptime).c_str());
}
}
diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp
index b7c13b5f8..0f0e75a1d 100644
--- a/src/modules/m_spanningtree/uid.cpp
+++ b/src/modules/m_spanningtree/uid.cpp
@@ -64,9 +64,9 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist &params)
}
/* check for collision */
- user_hash::iterator iter = this->ServerInstance->Users->clientlist->find(params[2]);
+ user_hash::iterator iter = ServerInstance->Users->clientlist->find(params[2]);
- if (iter != this->ServerInstance->Users->clientlist->end())
+ if (iter != ServerInstance->Users->clientlist->end())
{
/*
* Nick collision.
@@ -87,19 +87,19 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist &params)
User* _new = NULL;
try
{
- _new = new User(this->ServerInstance, params[0]);
+ _new = new User(ServerInstance, params[0]);
}
catch (...)
{
this->SendError("Protocol violation - Duplicate UUID '" + params[0] + "' on introduction of new user");
return false;
}
- (*(this->ServerInstance->Users->clientlist))[params[2]] = _new;
+ (*(ServerInstance->Users->clientlist))[params[2]] = _new;
_new->SetFd(FD_MAGIC_NUMBER);
_new->nick.assign(params[2], 0, MAXBUF);
_new->host.assign(params[3], 0, 64);
_new->dhost.assign(params[4], 0, 64);
- _new->server = this->ServerInstance->FindServerNamePtr(remoteserver->GetName().c_str());
+ _new->server = ServerInstance->FindServerNamePtr(remoteserver->GetName().c_str());
_new->ident.assign(params[5], 0, MAXBUF);
_new->fullname.assign(params[params.size() - 1], 0, MAXBUF);
_new->registered = REG_ALL;
@@ -164,11 +164,11 @@ bool TreeSocket::ParseUID(const std::string &source, parameterlist &params)
bool dosend = true;
- if ((this->Utils->quiet_bursts && remoteserver->bursting) || this->ServerInstance->SilentULine(_new->server))
+ if ((this->Utils->quiet_bursts && remoteserver->bursting) || ServerInstance->SilentULine(_new->server))
dosend = false;
if (dosend)
- this->ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server, _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
+ ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server, _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str());
params[params.size() - 1] = ":" + params[params.size() - 1];
Utils->DoOneToAllButSender(source, "UID", params, source);
diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp
index b37aecc4b..8d3c55758 100644
--- a/src/modules/m_spanningtree/utils.cpp
+++ b/src/modules/m_spanningtree/utils.cpp
@@ -49,19 +49,18 @@ void ServerSocketListener::OnAcceptReady(int newsock)
if (!found)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip);
+ ServerInstance->SNO->WriteToSnoMask('l', "Server connection from %s denied (no link blocks with that IP address)", ip);
ServerInstance->SE->Close(newsock);
return;
}
}
- if (this->GetIOHook())
- {
- this->GetIOHook()->OnRawSocketAccept(newsock, &client, &server);
- }
+ /* we don't need to do anything with the pointer, creating it stores it in the necessary places */
+ TreeSocket* ts = new TreeSocket(Utils, newsock, ip, NULL, Hook);
+
+ if (Hook)
+ Hook->OnStreamSocketAccept(ts, &client, &server);
- /* we don't need a pointer to this, creating it stores it in the necessary places */
- new TreeSocket(this->Utils, this->ServerInstance, newsock, ip, NULL, this->GetIOHook());
return;
}
@@ -73,7 +72,7 @@ void ServerSocketListener::OnAcceptReady(int newsock)
*/
TreeServer* SpanningTreeUtilities::FindServer(const std::string &ServerName)
{
- if (this->ServerInstance->IsSID(ServerName))
+ if (ServerInstance->IsSID(ServerName))
return this->FindServerID(ServerName);
server_hash::iterator iter = serverlist.find(ServerName.c_str());
@@ -150,12 +149,10 @@ bool SpanningTreeUtilities::IsServer(const std::string &ServerName)
SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningTree* C) : ServerInstance(Instance), Creator(C)
{
- Bindings.clear();
-
ServerInstance->Logs->Log("m_spanningtree",DEBUG,"***** Using SID for hash: %s *****", ServerInstance->Config->GetSID().c_str());
this->TreeRoot = new TreeServer(this, ServerInstance, ServerInstance->Config->ServerName, ServerInstance->Config->ServerDesc, ServerInstance->Config->GetSID());
- this->ServerUser = new FakeUser(ServerInstance, TreeRoot->GetID());
+ ServerUser = new FakeUser(ServerInstance, TreeRoot->GetID());
this->ReadConfiguration(true);
}
@@ -182,7 +179,6 @@ SpanningTreeUtilities::~SpanningTreeUtilities()
ServerUser->uuid = TreeRoot->GetID();
delete TreeRoot;
delete ServerUser;
- ServerInstance->BufferedSocketCull();
}
void SpanningTreeUtilities::AddThisServer(TreeServer* server, TreeServerList &list)
@@ -465,7 +461,6 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
{
delete Bindings[i];
}
- ServerInstance->BufferedSocketCull();
Bindings.clear();
for (int j = 0; j < Conf->Enumerate("bind"); j++)
@@ -498,7 +493,7 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
}
if (!transport.empty())
- listener->AddIOHook(hooks[transport.c_str()]);
+ listener->Hook = hooks[transport.c_str()];
Bindings.push_back(listener);
}
@@ -656,7 +651,7 @@ void SpanningTreeUtilities::DoFailOver(Autoconnect* x)
{
if (x->FailOver == x->Server)
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Some muppet configured the failover for server \002%s\002 to point at itself. Not following it!", x->Server.c_str());
return;
}
Link* TryThisOne = this->FindLink(x->FailOver.c_str());
@@ -669,13 +664,13 @@ void SpanningTreeUtilities::DoFailOver(Autoconnect* x)
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Trying failover link for \002%s\002: \002%s\002...", x->Server.c_str(), TryThisOne->Name.c_str());
Creator->ConnectServer(TryThisOne, NULL);
}
}
else
{
- this->ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str());
+ ServerInstance->SNO->WriteToSnoMask('l', "FAILOVER: Invalid failover server specified for server \002%s\002, will not follow!", x->Server.c_str());
}
}
}
diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h
index 09c707131..1bdf127d8 100644
--- a/src/modules/m_spanningtree/utils.h
+++ b/src/modules/m_spanningtree/utils.h
@@ -47,8 +47,11 @@ class ServerSocketListener : public ListenSocketBase
ServerSocketListener(InspIRCd* Instance, SpanningTreeUtilities *u, int port, char* addr) : ListenSocketBase(Instance, port, addr)
{
this->Utils = u;
+ Hook = NULL;
}
+ Module* Hook;
+
virtual void OnAcceptReady(int nfd);
};
diff --git a/src/modules/m_spanningtree/whois.cpp b/src/modules/m_spanningtree/whois.cpp
index f12a7f109..79e2d7355 100644
--- a/src/modules/m_spanningtree/whois.cpp
+++ b/src/modules/m_spanningtree/whois.cpp
@@ -28,13 +28,13 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist &params)
{
if (params.size() < 1)
return true;
- User* u = this->ServerInstance->FindNick(prefix);
+ User* u = ServerInstance->FindNick(prefix);
if (u)
{
// an incoming request
if (params.size() == 1)
{
- User* x = this->ServerInstance->FindNick(params[0]);
+ User* x = ServerInstance->FindNick(params[0]);
if ((x) && (IS_LOCAL(x)))
{
char signon[MAXBUF];
@@ -58,7 +58,7 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist &params)
else if (params.size() == 3)
{
std::string who_did_the_whois = params[0];
- User* who_to_send_to = this->ServerInstance->FindNick(who_did_the_whois);
+ User* who_to_send_to = ServerInstance->FindNick(who_did_the_whois);
if ((who_to_send_to) && (IS_LOCAL(who_to_send_to)))
{
// an incoming reply to a whois we sent out
diff --git a/src/socket.cpp b/src/socket.cpp
index ccae48a6d..cc9cb79b9 100644
--- a/src/socket.cpp
+++ b/src/socket.cpp
@@ -273,7 +273,7 @@ std::string irc::sockets::satouser(const irc::sockets::sockaddrs* sa) {
return std::string(buffer);
}
-int irc::sockets::sa_size(irc::sockets::sockaddrs& sa)
+int irc::sockets::sa_size(const irc::sockets::sockaddrs& sa)
{
if (sa.sa.sa_family == AF_INET)
return sizeof(sa.in4);
diff --git a/src/socketengine.cpp b/src/socketengine.cpp
index af2f1b169..c0ae3f278 100644
--- a/src/socketengine.cpp
+++ b/src/socketengine.cpp
@@ -43,35 +43,7 @@
EventHandler::EventHandler()
{
- this->IOHook = NULL;
-}
-
-bool EventHandler::AddIOHook(Module *IOHooker)
-{
- if (this->IOHook)
- return false;
-
- this->IOHook = IOHooker;
- return true;
-}
-
-bool EventHandler::DelIOHook()
-{
- if (!this->IOHook)
- return false;
-
- this->IOHook = NULL;
- return true;
-}
-
-Module *EventHandler::GetIOHook()
-{
- return this->IOHook;
-}
-
-int EventHandler::GetFd()
-{
- return this->fd;
+ fd = -1;
}
void EventHandler::SetFd(int FD)
@@ -79,21 +51,7 @@ void EventHandler::SetFd(int FD)
this->fd = FD;
}
-bool EventHandler::Readable()
-{
- return true;
-}
-
-bool EventHandler::Writeable()
-{
- return false;
-}
-
-void SocketEngine::WantWrite(EventHandler* eh)
-{
-}
-
-SocketEngine::SocketEngine(InspIRCd* Instance) : ServerInstance(Instance)
+SocketEngine::SocketEngine()
{
TotalEvents = WriteEvents = ReadEvents = ErrorEvents = 0;
lastempty = ServerInstance->Time();
@@ -104,11 +62,6 @@ SocketEngine::~SocketEngine()
{
}
-bool SocketEngine::AddFd(EventHandler* eh)
-{
- return true;
-}
-
bool SocketEngine::HasFd(int fd)
{
if ((fd < 0) || (fd > MAX_DESCRIPTORS))
@@ -123,11 +76,6 @@ EventHandler* SocketEngine::GetRef(int fd)
return ref[fd];
}
-bool SocketEngine::DelFd(EventHandler* eh, bool force)
-{
- return true;
-}
-
int SocketEngine::GetMaxFds()
{
return 0;
@@ -143,11 +91,6 @@ int SocketEngine::DispatchEvents()
return 0;
}
-std::string SocketEngine::GetName()
-{
- return "misconfigured";
-}
-
bool SocketEngine::BoundsCheckFd(EventHandler* eh)
{
if (!eh)
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index 1be0d7cd2..7fed6f250 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -16,7 +16,7 @@
#include "socketengines/socketengine_epoll.h"
#include <ulimit.h>
-EPollEngine::EPollEngine(InspIRCd* Instance) : SocketEngine(Instance)
+EPollEngine::EPollEngine()
{
MAX_DESCRIPTORS = 0;
// This is not a maximum, just a hint at the eventual number of sockets that may be polled.
@@ -45,7 +45,7 @@ EPollEngine::~EPollEngine()
delete[] events;
}
-bool EPollEngine::AddFd(EventHandler* eh)
+bool EPollEngine::AddFd(EventHandler* eh, bool writeFirst)
{
int fd = eh->GetFd();
if ((fd < 0) || (fd > GetMaxFds() - 1))
@@ -68,7 +68,7 @@ bool EPollEngine::AddFd(EventHandler* eh)
struct epoll_event ev;
memset(&ev,0,sizeof(ev));
- eh->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
+ ev.events = writeFirst ? EPOLLOUT : EPOLLIN;
ev.data.fd = fd;
int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev);
if (i < 0)
@@ -107,7 +107,6 @@ bool EPollEngine::DelFd(EventHandler* eh, bool force)
struct epoll_event ev;
memset(&ev,0,sizeof(ev));
- eh->Readable() ? ev.events = EPOLLIN : ev.events = EPOLLOUT;
ev.data.fd = fd;
int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev);
diff --git a/src/socketengines/socketengine_iocp.cpp b/src/socketengines/socketengine_iocp.cpp
index ee2e5afa1..3c3181909 100644
--- a/src/socketengines/socketengine_iocp.cpp
+++ b/src/socketengines/socketengine_iocp.cpp
@@ -15,7 +15,7 @@
#include "exitcodes.h"
#include <mswsock.h>
-IOCPEngine::IOCPEngine(InspIRCd * Instance) : SocketEngine(Instance)
+IOCPEngine::IOCPEngine()
{
MAX_DESCRIPTORS = 10240;
@@ -47,7 +47,7 @@ IOCPEngine::~IOCPEngine()
delete[] ref;
}
-bool IOCPEngine::AddFd(EventHandler* eh)
+bool IOCPEngine::AddFd(EventHandler* eh, bool writeFirst)
{
/* Does it at least look valid? */
if (!eh)
@@ -92,7 +92,7 @@ bool IOCPEngine::AddFd(EventHandler* eh)
ServerInstance->Logs->Log("SOCKET",DEBUG, "New fake fd: %u, real fd: %u, address 0x%p", *fake_fd, eh->GetFd(), eh);
/* post a write event if there is data to be written */
- if(eh->Writeable())
+ if(writeFirst)
WantWrite(eh);
/* we're all good =) */
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index bf09eaf74..cbe3e959d 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -19,7 +19,7 @@
#include "socketengines/socketengine_kqueue.h"
#include <sys/sysctl.h>
-KQueueEngine::KQueueEngine(InspIRCd* Instance) : SocketEngine(Instance)
+KQueueEngine::KQueueEngine()
{
MAX_DESCRIPTORS = 0;
this->RecoverFromFork();
@@ -54,7 +54,7 @@ KQueueEngine::~KQueueEngine()
delete[] ke_list;
}
-bool KQueueEngine::AddFd(EventHandler* eh)
+bool KQueueEngine::AddFd(EventHandler* eh, bool writeFirst)
{
int fd = eh->GetFd();
@@ -79,7 +79,7 @@ bool KQueueEngine::AddFd(EventHandler* eh)
return false;
}
- if (!eh->Readable()) {
+ if (writeFirst) {
// ...and sometimes want to write
WantWrite(eh);
}
diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp
index cee6a90cb..6d5ddb9f5 100644
--- a/src/socketengines/socketengine_poll.cpp
+++ b/src/socketengines/socketengine_poll.cpp
@@ -19,7 +19,7 @@
#include <sys/sysctl.h>
#endif
-PollEngine::PollEngine(InspIRCd* Instance) : SocketEngine(Instance)
+PollEngine::PollEngine()
{
// Poll requires no special setup (which is nice).
CurrentSetSize = 0;
@@ -39,7 +39,7 @@ PollEngine::~PollEngine()
delete[] events;
}
-bool PollEngine::AddFd(EventHandler* eh)
+bool PollEngine::AddFd(EventHandler* eh, bool writeFirst)
{
int fd = eh->GetFd();
if ((fd < 0) || (fd > GetMaxFds() - 1))
@@ -65,13 +65,13 @@ bool PollEngine::AddFd(EventHandler* eh)
fd_mappings[fd] = index;
ref[index] = eh;
events[index].fd = fd;
- if (eh->Readable())
+ if (writeFirst)
{
- events[index].events = POLLIN;
+ events[index].events = POLLOUT;
}
else
{
- events[index].events = POLLOUT;
+ events[index].events = POLLIN;
}
ServerInstance->Logs->Log("SOCKET", DEBUG,"New file descriptor: %d (%d; index %d)", fd, events[fd].events, index);
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index 5efa545b0..eb08839d0 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -17,7 +17,7 @@
#include "socketengines/socketengine_ports.h"
#include <ulimit.h>
-PortsEngine::PortsEngine(InspIRCd* Instance) : SocketEngine(Instance)
+PortsEngine::PortsEngine()
{
MAX_DESCRIPTORS = 0;
EngineHandle = port_create();
@@ -44,7 +44,7 @@ PortsEngine::~PortsEngine()
delete[] events;
}
-bool PortsEngine::AddFd(EventHandler* eh)
+bool PortsEngine::AddFd(EventHandler* eh, bool writeFirst)
{
int fd = eh->GetFd();
if ((fd < 0) || (fd > GetMaxFds() - 1))
@@ -57,7 +57,7 @@ bool PortsEngine::AddFd(EventHandler* eh)
return false;
ref[fd] = eh;
- port_associate(EngineHandle, PORT_SOURCE_FD, fd, eh->Readable() ? POLLRDNORM : POLLWRNORM, eh);
+ port_associate(EngineHandle, PORT_SOURCE_FD, fd, writeFirst ? POLLWRNORM : POLLRDNORM, eh);
ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd);
CurrentSetSize++;
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index 8c41df11b..7f6a4e283 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -18,7 +18,7 @@
#include "socketengines/socketengine_select.h"
-SelectEngine::SelectEngine(InspIRCd* Instance) : SocketEngine(Instance)
+SelectEngine::SelectEngine()
{
MAX_DESCRIPTORS = FD_SETSIZE;
EngineHandle = 0;
@@ -34,7 +34,7 @@ SelectEngine::~SelectEngine()
delete[] ref;
}
-bool SelectEngine::AddFd(EventHandler* eh)
+bool SelectEngine::AddFd(EventHandler* eh, bool writeFirst)
{
int fd = eh->GetFd();
if ((fd < 0) || (fd > GetMaxFds() - 1))
@@ -50,6 +50,8 @@ bool SelectEngine::AddFd(EventHandler* eh)
ref[fd] = eh;
CurrentSetSize++;
+ writeable[eh->GetFd()] = writeFirst;
+
ServerInstance->Logs->Log("SOCKET",DEBUG,"New file descriptor: %d", fd);
return true;
}
@@ -101,16 +103,11 @@ int SelectEngine::DispatchEvents()
/* Populate the select FD set (this is why select sucks compared to epoll, kqueue, IOCP) */
for (std::set<int>::iterator a = fds.begin(); a != fds.end(); a++)
{
- if (ref[*a]->Readable())
- /* Read notifications */
- FD_SET (*a, &rfdset);
- else
- /* Write notifications */
- FD_SET (*a, &wfdset);
-
/* Explicitly one-time writeable */
if (writeable[*a])
FD_SET (*a, &wfdset);
+ else
+ FD_SET (*a, &rfdset);
/* All sockets must receive error notifications regardless */
FD_SET (*a, &errfdset);
diff --git a/src/stats.cpp b/src/stats.cpp
index 40ee40b18..02cfeaa7c 100644
--- a/src/stats.cpp
+++ b/src/stats.cpp
@@ -254,7 +254,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results)
for (std::vector<User*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++)
{
User* i = *n;
- results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age));
}
break;
@@ -264,7 +264,7 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results)
for (std::vector<User*>::iterator n = this->Users->local_users.begin(); n != this->Users->local_users.end(); n++)
{
User* i = *n;
- results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age));
+ results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->getSendQSize())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(this->Time() - i->age));
}
break;
diff --git a/src/threadengines/threadengine_pthread.cpp b/src/threadengines/threadengine_pthread.cpp
index 6e32634c5..a4a47f8fa 100644
--- a/src/threadengines/threadengine_pthread.cpp
+++ b/src/threadengines/threadengine_pthread.cpp
@@ -65,8 +65,7 @@ class ThreadSignalSocket : public BufferedSocket
{
SocketThread* parent;
public:
- ThreadSignalSocket(SocketThread* p, InspIRCd* SI, int newfd) :
- BufferedSocket(SI, newfd, const_cast<char*>("0.0.0.0")), parent(p) {}
+ ThreadSignalSocket(SocketThread* p, int newfd) : BufferedSocket(newfd), parent(p) {}
~ThreadSignalSocket()
{
@@ -77,13 +76,14 @@ class ThreadSignalSocket : public BufferedSocket
eventfd_write(fd, 1);
}
- virtual bool OnDataReady()
+ void OnDataReady()
{
- eventfd_t data;
- if (eventfd_read(fd, &data))
- return false;
+ recvq.clear();
parent->OnNotify();
- return true;
+ }
+
+ void OnError(BufferedSocketError)
+ {
}
};
@@ -92,7 +92,7 @@ SocketThread::SocketThread(InspIRCd* SI)
int fd = eventfd(0, O_NONBLOCK);
if (fd < 0)
throw new CoreException("Could not create pipe " + std::string(strerror(errno)));
- signal.sock = new ThreadSignalSocket(this, SI, fd);
+ signal.sock = new ThreadSignalSocket(this, fd);
}
#else
@@ -101,8 +101,8 @@ class ThreadSignalSocket : public BufferedSocket
SocketThread* parent;
int send_fd;
public:
- ThreadSignalSocket(SocketThread* p, InspIRCd* SI, int recvfd, int sendfd) :
- BufferedSocket(SI, recvfd, const_cast<char*>("0.0.0.0")), parent(p), send_fd(sendfd) {}
+ ThreadSignalSocket(SocketThread* p, int recvfd, int sendfd) :
+ BufferedSocket(recvfd), parent(p), send_fd(sendfd) {}
~ThreadSignalSocket()
{
@@ -115,13 +115,14 @@ class ThreadSignalSocket : public BufferedSocket
write(send_fd, &dummy, 1);
}
- virtual bool OnDataReady()
+ void OnDataReady()
{
- char data;
- if (read(this->fd, &data, 1) <= 0)
- return false;
+ recvq.clear();
parent->OnNotify();
- return true;
+ }
+
+ void OnError(BufferedSocketError)
+ {
}
};
@@ -130,7 +131,7 @@ SocketThread::SocketThread(InspIRCd* SI)
int fds[2];
if (pipe(fds))
throw new CoreException("Could not create pipe " + std::string(strerror(errno)));
- signal.sock = new ThreadSignalSocket(this, SI, fds[0], fds[1]);
+ signal.sock = new ThreadSignalSocket(this, fds[0], fds[1]);
}
#endif
diff --git a/src/threadengines/threadengine_win32.cpp b/src/threadengines/threadengine_win32.cpp
index 5c62b5081..fab75699e 100644
--- a/src/threadengines/threadengine_win32.cpp
+++ b/src/threadengines/threadengine_win32.cpp
@@ -55,20 +55,15 @@ class ThreadSignalSocket : public BufferedSocket
{
SocketThread* parent;
public:
- ThreadSignalSocket(SocketThread* t, InspIRCd* SI, int newfd, const char* ip)
- : BufferedSocket(SI, newfd, ip), parent(t)
+ ThreadSignalSocket(SocketThread* t, int newfd)
+ : BufferedSocket(newfd), parent(t)
{
}
- virtual bool OnDataReady()
+ void OnDataReady()
{
- char data = 0;
- if (ServerInstance->SE->Recv(this, &data, 1, 0) > 0)
- {
- parent->OnNotify();
- return true;
- }
- return false;
+ recvq.clear();
+ parent->OnNotify();
}
};
@@ -92,7 +87,7 @@ SocketThread::SocketThread(InspIRCd* SI)
int nfd = accept(listenFD);
if (nfd < 0)
throw CoreException("Could not create ITC pipe");
- new ThreadSignalSocket(parent, ServerInstance, nfd, "127.0.0.1");
+ new ThreadSignalSocket(parent, nfd);
closesocket(listenFD);
SI->SE->Blocking(connFD);
diff --git a/src/usermanager.cpp b/src/usermanager.cpp
index b9eff5a39..6d04bdff7 100644
--- a/src/usermanager.cpp
+++ b/src/usermanager.cpp
@@ -46,7 +46,7 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, ClientListenSocket* vi
{
try
{
- New->GetIOHook()->OnRawSocketAccept(socket, client, server);
+ New->GetIOHook()->OnStreamSocketAccept(New, client, server);
}
catch (CoreException& modexcept)
{
@@ -201,24 +201,18 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
FOREACH_MOD_I(ServerInstance,I_OnUserDisconnect,OnUserDisconnect(user));
- user->UpdateNickHash(user->uuid.c_str());
-
- user_hash::iterator iter = this->clientlist->find(user->uuid);
-
if (user->registered != REG_ALL)
if (ServerInstance->Users->unregistered_count)
ServerInstance->Users->unregistered_count--;
if (IS_LOCAL(user))
{
- if (!user->sendq.empty())
- user->FlushWriteBuf();
-
+ user->DoWrite();
if (user->GetIOHook())
{
try
{
- user->GetIOHook()->OnRawSocketClose(user->GetFd());
+ user->GetIOHook()->OnStreamSocketClose(user);
}
catch (CoreException& modexcept)
{
@@ -227,7 +221,9 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
}
ServerInstance->SE->DelFd(user);
- user->CloseSocket();
+ user->Close();
+ // user->Close() will set fd to -1; this breaks IS_LOCAL. Fix
+ user->SetFd(INT_MAX);
}
/*
@@ -255,19 +251,12 @@ void UserManager::QuitUser(User *user, const std::string &quitreason, const char
user->AddToWhoWas();
}
+ user_hash::iterator iter = this->clientlist->find(user->nick);
+
if (iter != this->clientlist->end())
this->clientlist->erase(iter);
else
ServerInstance->Logs->Log("USERS", DEBUG, "iter == clientlist->end, can't remove them from hash... problematic..");
-
- if (IS_LOCAL(user))
- {
- std::vector<User*>::iterator x = find(local_users.begin(),local_users.end(),user);
- if (x != local_users.end())
- local_users.erase(x);
- else
- ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector");
- }
}
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 4fcf87f66..b150f2828 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -36,102 +36,6 @@ void FloodQuitUserHandler::Call(User* current)
}
}
-void ProcessUserHandler::Call(User* cu)
-{
- int result = EAGAIN;
-
- if (cu->GetFd() == FD_MAGIC_NUMBER)
- return;
-
- char* ReadBuffer = Server->GetReadBuffer();
-
- if (cu->GetIOHook())
- {
- int result2 = 0;
- int MOD_RESULT = 0;
-
- try
- {
- MOD_RESULT = cu->GetIOHook()->OnRawSocketRead(cu->GetFd(), ReadBuffer, Server->Config->NetBufferSize, result2);
- }
- catch (CoreException& modexcept)
- {
- Server->Logs->Log("USERS",DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
- }
-
- if (MOD_RESULT < 0)
- {
- result = -EAGAIN;
- }
- else
- {
- result = result2;
- }
- }
- else
- {
- result = cu->ReadData(ReadBuffer, Server->Config->NetBufferSize);
- }
-
- if ((result) && (result != -EAGAIN))
- {
- User *current;
- int currfd;
-
- Server->stats->statsRecv += result;
- /*
- * perform a check on the raw buffer as an array (not a string!) to remove
- * character 0 which is illegal in the RFC - replace them with spaces.
- */
-
- for (int checker = 0; checker < result; checker++)
- {
- if (ReadBuffer[checker] == 0)
- ReadBuffer[checker] = ' ';
- }
-
- if (result > 0)
- ReadBuffer[result] = '\0';
-
- current = cu;
- currfd = current->GetFd();
-
- // add the data to the users buffer
- if (result > 0)
- {
- if (!current->AddBuffer(ReadBuffer))
- {
- // AddBuffer returned false, theres too much data in the user's buffer and theyre up to no good.
- Server->FloodQuitUser(current);
- return;
- }
-
- /* If user is over penalty, dont process here, just build up */
- if (current->Penalty < 10)
- Server->Parser->DoLines(current);
-
- return;
- }
-
- if ((result == -1) && (errno != EAGAIN) && (errno != EINTR))
- {
- Server->Users->QuitUser(cu, errno ? strerror(errno) : "EOF from client");
- return;
- }
- }
-
- // result EAGAIN means nothing read
- else if ((result == EAGAIN) || (result == -EAGAIN))
- {
- /* do nothing */
- }
- else if (result == 0)
- {
- Server->Users->QuitUser(cu, "Connection closed");
- return;
- }
-}
-
/**
* This function is called once a second from the mainloop.
* It is intended to do background checking on all the user structs, e.g.
@@ -154,8 +58,12 @@ void InspIRCd::DoBackgroundUserStuff()
if (curr->Penalty)
{
curr->Penalty--;
- if (curr->Penalty < 10)
- Parser->DoLines(curr, true);
+ curr->OnDataReady();
+ }
+
+ if (curr->getSendQSize() == 0)
+ {
+ FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(curr));
}
switch (curr->registered)
diff --git a/src/users.cpp b/src/users.cpp
index fd0c168d9..5d6b1a01a 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -216,12 +216,8 @@ User::User(InspIRCd* Instance, const std::string &uid)
fd = -1;
server_sa.sa.sa_family = AF_UNSPEC;
client_sa.sa.sa_family = AF_UNSPEC;
- recvq.clear();
- sendq.clear();
MyClass = NULL;
AllowedPrivs = AllowedOperCommands = NULL;
- chans.clear();
- invites.clear();
if (uid.empty())
uuid.assign(Instance->GetUID(), 0, UUID_LENGTH - 1);
@@ -309,15 +305,6 @@ const std::string& User::MakeHostIP()
return this->cached_hostip;
}
-void User::CloseSocket()
-{
- if (this->fd > -1)
- {
- ServerInstance->SE->Shutdown(this, 2);
- ServerInstance->SE->Close(this);
- }
-}
-
const std::string User::GetFullHost()
{
if (!this->cached_fullhost.empty())
@@ -352,21 +339,6 @@ char* User::MakeWildHost()
return nresult;
}
-int User::ReadData(void* buffer, size_t size)
-{
- if (IS_LOCAL(this))
- {
-#ifndef WIN32
- return read(this->fd, buffer, size);
-#else
- return recv(this->fd, (char*)buffer, size, 0);
-#endif
- }
- else
- return 0;
-}
-
-
const std::string User::GetFullRealHost()
{
if (!this->cached_fullrealhost.empty())
@@ -540,123 +512,60 @@ bool User::HasPrivPermission(const std::string &privstr, bool noisy)
return false;
}
-bool User::AddBuffer(const std::string &a)
+void User::OnDataReady()
{
- std::string::size_type start = 0;
- std::string::size_type i = a.find('\r');
-
- /*
- * The old implementation here took a copy, and rfind() on \r, removing as it found them, before
- * copying a second time onto the recvq. That's ok, but involves three copies minimum (recv() to buffer,
- * buffer to here, here to recvq) - The new method now copies twice (recv() to buffer, buffer to recvq).
- *
- * We use find() instead of rfind() for clarity, however unlike the old code, our scanning of the string is
- * contiguous: as we specify a startpoint, we never see characters we have scanned previously, making this
- * marginally faster in cases with a number of \r hidden early on in the buffer.
- *
- * How it works:
- * Start at first pos of string, find first \r, append everything in the chunk (excluding \r) to recvq. Set
- * i ahead of the \r, search for next \r, add next chunk to buffer... repeat.
- * -- w00t (7 may, 2008)
- */
- if (i == std::string::npos)
- {
- // no \r that we need to dance around, just add to buffer
- recvq.append(a);
- }
- else
- {
- // While we can find the end of a chunk to add
- while (i != std::string::npos)
- {
- // Append the chunk that we have
- recvq.append(a, start, (i - start));
-
- // Start looking for the next one
- start = i + 1;
- i = a.find('\r', start);
- }
-
- if (start != a.length())
- {
- /*
- * This is here to catch a corner case when we get something like:
- * NICK w0
- * 0t\r\nU
- * SER ...
- * in successive calls to us.
- *
- * Without this conditional, the 'U' on the second case will be dropped,
- * which is most *certainly* not the behaviour we want!
- * -- w00t
- */
- recvq.append(a, start, (a.length() - start));
- }
- }
+ if (quitting)
+ return;
- if (this->MyClass && !this->HasPrivPermission("users/flood/increased-buffers") && recvq.length() > this->MyClass->GetRecvqMax())
+ if (MyClass && !HasPrivPermission("users/flood/increased-buffers") && recvq.length() > MyClass->GetRecvqMax())
{
ServerInstance->Users->QuitUser(this, "RecvQ exceeded");
- ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)recvq.length(),this->MyClass->GetRecvqMax());
- return false;
+ ServerInstance->SNO->WriteToSnoMask('a', "User %s RecvQ of %lu exceeds connect class maximum of %lu",
+ nick.c_str(), (unsigned long)recvq.length(), MyClass->GetRecvqMax());
}
- return true;
-}
-
-bool User::BufferIsReady()
-{
- return (recvq.find('\n') != std::string::npos);
-}
-
-void User::ClearBuffer()
-{
- recvq.clear();
-}
-
-std::string User::GetBuffer()
-{
- try
+ while (this->Penalty < 10)
{
- if (recvq.empty())
- return "";
-
- /* Strip any leading \r or \n off the string.
- * Usually there are only one or two of these,
- * so its is computationally cheap to do.
- */
- std::string::iterator t = recvq.begin();
- while (t != recvq.end() && (*t == '\r' || *t == '\n'))
- {
- recvq.erase(t);
- t = recvq.begin();
- }
-
- for (std::string::iterator x = recvq.begin(); x != recvq.end(); x++)
+ std::string line;
+ line.reserve(MAXBUF);
+ std::string::size_type qpos = 0;
+ while (qpos < recvq.length())
{
- /* Find the first complete line, return it as the
- * result, and leave the recvq as whats left
- */
- if (*x == '\n')
+ char c = recvq[qpos++];
+ switch (c)
{
- std::string ret = std::string(recvq.begin(), x);
- recvq.erase(recvq.begin(), x + 1);
- return ret;
+ case '\0':
+ c = ' ';
+ break;
+ case '\r':
+ continue;
+ case '\n':
+ goto eol_found;
}
+ if (line.length() < MAXBUF - 2)
+ line.push_back(c);
}
- return "";
- }
+ // if we got here, the recvq ran out before we found a newline
+ return;
+eol_found:
+ // just found a newline. Terminate the string, and pull it out of recvq
+ recvq = recvq.substr(qpos);
- catch (...)
- {
- ServerInstance->Logs->Log("USERS", DEBUG,"Exception in User::GetBuffer()");
- return "";
+ // TODO should this be moved to when it was inserted in recvq?
+ ServerInstance->stats->statsRecv += qpos;
+ this->bytes_in += qpos;
+ this->cmds_in++;
+
+ ServerInstance->Parser->ProcessBuffer(line, this);
}
}
void User::AddWriteBuf(const std::string &data)
{
- if (!this->quitting && this->MyClass && !this->HasPrivPermission("users/flood/increased-buffers") && sendq.length() + data.length() > this->MyClass->GetSendqMax())
+ // Don't bother sending text to remote users!
+ if (IS_REMOTE(this))
+ return;
+ if (!quitting && MyClass && getSendQSize() + data.length() > MyClass->GetSendqMax() && !HasPrivPermission("users/flood/increased-buffers"))
{
/*
* Fix by brain - Set the error text BEFORE calling, because
@@ -664,66 +573,36 @@ void User::AddWriteBuf(const std::string &data)
* to repeatedly add the text to the sendq!
*/
ServerInstance->Users->QuitUser(this, "SendQ exceeded");
- ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ of %lu exceeds connect class maximum of %lu",this->nick.c_str(),(unsigned long int)sendq.length() + data.length(),this->MyClass->GetSendqMax());
+ ServerInstance->SNO->WriteToSnoMask('a', "User %s SendQ of %lu exceeds connect class maximum of %lu",
+ nick.c_str(), (unsigned long)getSendQSize() + data.length(), MyClass->GetSendqMax());
return;
}
// We still want to append data to the sendq of a quitting user,
// e.g. their ERROR message that says 'closing link'
- if (data.length() > MAXBUF - 2) /* MAXBUF has a value of 514, to account for line terminators */
- sendq.append(data.substr(0,MAXBUF - 4)).append("\r\n"); /* MAXBUF-4 = 510 */
- else
- sendq.append(data);
+ WriteData(data);
}
-// send AS MUCH OF THE USERS SENDQ as we are able to (might not be all of it)
-void User::FlushWriteBuf()
+void User::OnError(BufferedSocketError)
{
- if (this->fd == FD_MAGIC_NUMBER)
- {
- sendq.clear();
- return;
- }
+ ServerInstance->Users->QuitUser(this, getError());
+}
- if ((sendq.length()) && (this->fd != FD_MAGIC_NUMBER))
+void User::cull()
+{
+ if (!quitting)
+ ServerInstance->Users->QuitUser(this, "Culled without QuitUser");
+ if (IS_LOCAL(this))
{
- int old_sendq_length = sendq.length();
- int n_sent = ServerInstance->SE->Send(this, this->sendq.data(), this->sendq.length(), 0);
+ if (fd != INT_MAX)
+ Close();
- if (n_sent == -1)
- {
- if (errno == EAGAIN)
- {
- /* The socket buffer is full. This isnt fatal,
- * try again later.
- */
- ServerInstance->SE->WantWrite(this);
- }
- else
- {
- /* Fatal error, set write error and bail */
- ServerInstance->Users->QuitUser(this, errno ? strerror(errno) : "Write error");
- return;
- }
- }
+ std::vector<User*>::iterator x = find(ServerInstance->Users->local_users.begin(),ServerInstance->Users->local_users.end(),this);
+ if (x != ServerInstance->Users->local_users.end())
+ ServerInstance->Users->local_users.erase(x);
else
- {
- /* advance the queue */
- if (n_sent)
- this->sendq = this->sendq.substr(n_sent);
- /* update the user's stats counters */
- this->bytes_out += n_sent;
- this->cmds_out++;
- if (n_sent != old_sendq_length)
- ServerInstance->SE->WantWrite(this);
- }
- }
-
- /* note: NOT else if! */
- if (this->sendq.empty())
- {
- FOREACH_MOD(I_OnBufferFlushed,OnBufferFlushed(this));
+ ServerInstance->Logs->Log("USERS", DEBUG, "Failed to remove user from vector");
}
}
@@ -1191,35 +1070,29 @@ bool User::SetClientIP(const char* sip)
return irc::sockets::aptosa(sip, 0, &client_sa);
}
+static std::string wide_newline("\r\n");
+
void User::Write(const std::string& text)
{
if (!ServerInstance->SE->BoundsCheckFd(this))
return;
- ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%d] O %s", this->GetFd(), text.c_str());
-
- if (this->GetIOHook())
+ if (text.length() > MAXBUF - 2)
{
- /* XXX: The lack of buffering here is NOT a bug, modules implementing this interface have to
- * implement their own buffering mechanisms
- */
- try
- {
- this->GetIOHook()->OnRawSocketWrite(this->fd, text.data(), text.length());
- this->GetIOHook()->OnRawSocketWrite(this->fd, "\r\n", 2);
- }
- catch (CoreException& modexcept)
- {
- ServerInstance->Logs->Log("USEROUTPUT", DEBUG, "%s threw an exception: %s", modexcept.GetSource(), modexcept.GetReason());
- }
- }
- else
- {
- this->AddWriteBuf(text);
- this->AddWriteBuf("\r\n");
+ // this should happen rarely or never. Crop the string at 512 and try again.
+ std::string try_again = text.substr(0, MAXBUF - 2);
+ Write(try_again);
+ return;
}
+
+ ServerInstance->Logs->Log("USEROUTPUT", DEBUG,"C[%d] O %s", this->GetFd(), text.c_str());
+
+ this->AddWriteBuf(text);
+ this->AddWriteBuf(wide_newline);
+
ServerInstance->stats->statsSent += text.length() + 2;
- ServerInstance->SE->WantWrite(this);
+ this->bytes_out += text.length() + 2;
+ this->cmds_out++;
}
/** Write()
@@ -1904,25 +1777,6 @@ void User::ShowRULES()
this->WriteNumeric(RPL_RULESEND, "%s :End of RULES command.",this->nick.c_str());
}
-void User::HandleEvent(EventType et, int errornum)
-{
- if (this->quitting) // drop everything, user is due to be quit
- return;
-
- switch (et)
- {
- case EVENT_READ:
- ServerInstance->ProcessUser(this);
- break;
- case EVENT_WRITE:
- this->FlushWriteBuf();
- break;
- case EVENT_ERROR:
- ServerInstance->Users->QuitUser(this, errornum ? strerror(errornum) : "Client closed the connection");
- break;
- }
-}
-
void User::IncreasePenalty(int increase)
{
this->Penalty += increase;