]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - include/socketengine.h
Replace SocketEngine::GetName() with INSPIRCD_SOCKETENGINE_NAME define
[user/henk/code/inspircd.git] / include / socketengine.h
index e23c74de48f1265913c6c7fe5aedc0a01b1d2da2..a2179d951e7ee5726d3dda5617bb803380397b41 100644 (file)
@@ -1,23 +1,31 @@
-/*       +------------------------------------+
- *       | Inspire Internet Relay Chat Daemon |
- *       +------------------------------------+
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
  *
- *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
- * See: http://wiki.inspircd.org/Credits
+ *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *   Copyright (C) 2005-2007 Craig Edwards <craigedwards@brainbox.cc>
+ *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
  *
- * This program is free but copyrighted software; see
- *            the file COPYING for details.
+ * This file is part of InspIRCd.  InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
  *
- * ---------------------------------------------------
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __SOCKETENGINE__
-#define __SOCKETENGINE__
+
+#pragma once
 
 #include <vector>
 #include <string>
 #include <map>
-#include "inspircd_config.h"
+#include "config.h"
 #include "socket.h"
 #include "base.h"
 
@@ -119,7 +127,7 @@ enum EventMask
        /** Add a trial write. During the next DispatchEvents invocation, this
         * will call HandleEvent with EVENT_WRITE unless writes are known to be
         * blocking.
-        * 
+        *
         * This could be used to group several writes together into a single
         * send() syscall, or to ensure that writes are blocking when attempting
         * to use FD_WANT_FAST_WRITE.
@@ -128,7 +136,7 @@ enum EventMask
        /** Assert that writes are known to block. This cancels FD_ADD_TRIAL_WRITE.
         * Reset by SE before running EVENT_WRITE
         */
-       FD_WRITE_WILL_BLOCK = 0x8000, 
+       FD_WRITE_WILL_BLOCK = 0x8000,
 
        /** Mask for trial read/trial write */
        FD_TRIAL_NOTE_MASK = 0x5000
@@ -193,7 +201,9 @@ class CoreExport EventHandler : public classbase
         * class, and it will be called whenever read or write
         * events are received.
         * @param et either one of EVENT_READ for read events,
-        * and EVENT_WRITE for write events.
+        * EVENT_WRITE for write events and EVENT_ERROR for
+        * error events.
+        * @param errornum The error code which goes with an EVENT_ERROR.
         */
        virtual void HandleEvent(EventType et, int errornum = 0) = 0;
 
@@ -220,13 +230,14 @@ class CoreExport EventHandler : public classbase
  */
 class CoreExport SocketEngine
 {
+       /** Reference table, contains all current handlers
+        **/
+       std::vector<EventHandler*> ref;
+
  protected:
        /** Current number of descriptors in the engine
         */
-       int CurrentSetSize;
-       /** Reference table, contains all current handlers
-        */
-       EventHandler** ref;
+       size_t CurrentSetSize;
        /** List of handlers that want a trial read/write
         */
        std::set<int> trials;
@@ -241,6 +252,18 @@ class CoreExport SocketEngine
 
        virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask) = 0;
        void SetEventMask(EventHandler* eh, int value);
+
+       /** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this.
+        */
+       bool AddFd(EventHandler* eh);
+
+       template <typename T>
+       void ResizeDouble(std::vector<T>& vect)
+       {
+               if (CurrentSetSize > vect.size())
+                       vect.resize(vect.size() * 2);
+       }
+
 public:
 
        unsigned long TotalEvents;
@@ -294,7 +317,7 @@ public:
        /** Returns the number of file descriptors being queried
         * @return The set size
         */
-       inline int GetUsedFds() const { return CurrentSetSize; }
+       inline size_t GetUsedFds() const { return CurrentSetSize; }
 
        /** Delete an event handler from the engine.
         * This function call deletes an EventHandler
@@ -302,18 +325,9 @@ public:
         * and false if it failed. This does not free the
         * EventHandler pointer using delete, if this is
         * required you must do this yourself.
-        * Note on forcing deletes. DO NOT DO THIS! This is
-        * extremely dangerous and will most likely render the
-        * socketengine dead. This was added only for handling
-        * very rare cases where broken 3rd party libs destroys
-        * the OS socket beyond our control. If you can't explain
-        * in minute details why forcing is absolutely necessary
-        * then you don't need it. That was a NO!
         * @param eh The event handler object to remove
-        * @param force *DANGEROUS* See method description!
-        * @return True if the event handler was removed
         */
-       virtual bool DelFd(EventHandler* eh, bool force = false) = 0;
+       virtual void DelFd(EventHandler* eh);
 
        /** Returns true if a file descriptor exists in
         * the socket engine's list.
@@ -344,12 +358,6 @@ public:
         */
        virtual void DispatchTrialWrites();
 
-       /** Returns the socket engines name.  This returns the name of the
-        * engine for use in /VERSION responses.
-        * @return The socket engine name
-        */
-       virtual std::string GetName() = 0;
-
        /** Returns true if the file descriptors in the given event handler are
         * within sensible ranges which can be handled by the socket engine.
         */
@@ -358,27 +366,32 @@ public:
        /** Abstraction for BSD sockets accept(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param addr The client IP address and port
+        * @param addrlen The size of the sockaddr parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+       static int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
 
        /** Abstraction for BSD sockets close(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Close(EventHandler* fd);
+       static int Close(EventHandler* fd);
 
        /** Abstraction for BSD sockets close(2).
         * This function should emulate its namesake system call exactly.
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Close(int fd);
+       static int Close(int fd);
 
        /** Abstraction for BSD sockets send(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param buf The buffer in which the data that is sent is stored.
+        * @param len The size of the buffer.
+        * @param flags A flag value that controls the sending of the data.
         * @return This method should return exactly the same values as the system call it emulates.
         */
        int Send(EventHandler* fd, const void *buf, size_t len, int flags);
@@ -386,6 +399,9 @@ public:
        /** Abstraction for BSD sockets recv(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param buf The buffer in which the data that is read is stored.
+        * @param len The size of the buffer.
+        * @param flags A flag value that controls the reception of the data.
         * @return This method should return exactly the same values as the system call it emulates.
         */
        int Recv(EventHandler* fd, void *buf, size_t len, int flags);
@@ -393,6 +409,11 @@ public:
        /** Abstraction for BSD sockets recvfrom(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param buf The buffer in which the data that is read is stored.
+        * @param len The size of the buffer.
+        * @param flags A flag value that controls the reception of the data.
+        * @param from The remote IP address and port.
+        * @param fromlen The size of the from parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
        int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen);
@@ -400,6 +421,11 @@ public:
        /** Abstraction for BSD sockets sendto(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param buf The buffer in which the data that is sent is stored.
+        * @param len The size of the buffer.
+        * @param flags A flag value that controls the sending of the data.
+        * @param to The remote IP address and port.
+        * @param tolen The size of the to parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
        int SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen);
@@ -407,50 +433,53 @@ public:
        /** Abstraction for BSD sockets connect(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param serv_addr The server IP address and port.
+        * @param addrlen The size of the sockaddr parameter.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
+       static int Connect(EventHandler* fd, const sockaddr *serv_addr, socklen_t addrlen);
 
        /** Make a file descriptor blocking.
         * @param fd a file descriptor to set to blocking mode
         * @return 0 on success, -1 on failure, errno is set appropriately.
         */
-       int Blocking(int fd);
+       static int Blocking(int fd);
 
        /** Make a file descriptor nonblocking.
         * @param fd A file descriptor to set to nonblocking mode
         * @return 0 on success, -1 on failure, errno is set appropriately.
         */
-       int NonBlocking(int fd);
+       static int NonBlocking(int fd);
 
        /** Abstraction for BSD sockets shutdown(2).
         * This function should emulate its namesake system call exactly.
         * @param fd This version of the call takes an EventHandler instead of a bare file descriptor.
+        * @param how What part of the socket to shut down
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Shutdown(EventHandler* fd, int how);
+       static int Shutdown(EventHandler* fd, int how);
 
        /** Abstraction for BSD sockets shutdown(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Shutdown(int fd, int how);
+       static int Shutdown(int fd, int how);
 
        /** Abstraction for BSD sockets bind(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Bind(int fd, const irc::sockets::sockaddrs& addr);
+       static int Bind(int fd, const irc::sockets::sockaddrs& addr);
 
        /** Abstraction for BSD sockets listen(2).
         * This function should emulate its namesake system call exactly.
         * @return This method should return exactly the same values as the system call it emulates.
         */
-       int Listen(int sockfd, int backlog);
+       static int Listen(int sockfd, int backlog);
 
        /** Set SO_REUSEADDR and SO_LINGER on this file descriptor
         */
-       void SetReuse(int sockfd);
+       static void SetReuse(int sockfd);
 
        /** This function is called immediately after fork().
         * Some socket engines (notably kqueue) cannot have their
@@ -466,9 +495,32 @@ public:
        /** Get data transfer statistics, kilobits per second in and out and total.
         */
        void GetStats(float &kbitpersec_in, float &kbitpersec_out, float &kbitpersec_total);
+
+       /** Should we ignore the error in errno?
+        * Checks EAGAIN and WSAEWOULDBLOCK
+        */
+       static bool IgnoreError();
+
+       /** Return the last socket related error. strrerror(errno) on *nix
+        */
+       static std::string LastError();
+
+       /** Returns the error for the given error num, strerror(errnum) on *nix
+        */
+       static std::string GetError(int errnum);
 };
 
-SocketEngine* CreateSocketEngine();
+inline bool SocketEngine::IgnoreError()
+{
+       if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+               return true;
 
+#ifdef _WIN32
+       if (WSAGetLastError() == WSAEWOULDBLOCK)
+               return true;
 #endif
 
+       return false;
+}
+
+SocketEngine* CreateSocketEngine();