sockets.h

Go to the documentation of this file.
00001 /*
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  *
00011  */
00012 
00013 #ifndef SOCKETS_H
00014 #define SOCKETS_H
00015 
00016 #ifndef _WIN32
00017 #include <netinet/in.h>
00018 #include <sys/types.h>
00019 #include <sys/socket.h>
00020 #endif
00021 
00022 #include "anope.h"
00023 
00024 #define NET_BUFSIZE 65535
00025 
00028 union CoreExport sockaddrs
00029 {
00030         sockaddr sa;
00031         sockaddr_in sa4;
00032         sockaddr_in6 sa6;
00033 
00036         sockaddrs(const Anope::string &address = "");
00037 
00040         void clear();
00041 
00045         size_t size() const;
00046 
00050         int port() const;
00051 
00055         Anope::string addr() const;
00056 
00059         bool operator()() const;
00060 
00064         bool operator==(const sockaddrs &other) const;
00065         /* The same as above but not */
00066         inline bool operator!=(const sockaddrs &other) const { return !(*this == other); }
00067 
00074         void pton(int type, const Anope::string &address, int pport = 0);
00075 
00081         void ntop(int type, const void *src);
00082 };
00083 
00084 class CoreExport cidr
00085 {
00086         sockaddrs addr;
00087         Anope::string cidr_ip;
00088         unsigned short cidr_len;
00089  public:
00090         cidr(const Anope::string &ip);
00091         cidr(const Anope::string &ip, unsigned char len);
00092         Anope::string mask() const;
00093         bool match(const sockaddrs &other);
00094 
00095         bool operator<(const cidr &other) const;
00096         bool operator==(const cidr &other) const;
00097         bool operator!=(const cidr &other) const;
00098 
00099         struct CoreExport hash
00100         {
00101                 size_t operator()(const cidr &s) const;
00102         };
00103 };
00104 
00105 class SocketException : public CoreException
00106 {
00107  public:
00111         SocketException(const Anope::string &message) : CoreException(message) { }
00112 
00116         virtual ~SocketException() throw() { }
00117 };
00118 
00119 enum SocketFlag
00120 {
00121         SF_DEAD = 1,
00122         SF_READABLE,
00123         SF_WRITABLE,
00124         SF_CONNECTING,
00125         SF_CONNECTED,
00126         SF_ACCEPTING,
00127         SF_ACCEPTED,
00128         SF_SIZE
00129 };
00130 
00131 class CoreExport SocketIO
00132 {
00133  public:
00134         virtual ~SocketIO() { }
00135 
00142         virtual int Recv(Socket *s, char *buf, size_t sz);
00143 
00149         virtual int Send(Socket *s, const char *buf, size_t sz);
00150         int Send(Socket *s, const Anope::string &buf);
00151 
00156         virtual ClientSocket *Accept(ListenSocket *s);
00157 
00162         virtual SocketFlag FinishAccept(ClientSocket *cs);
00163 
00169         virtual void Bind(Socket *s, const Anope::string &ip, int port = 0);
00170 
00176         virtual void Connect(ConnectionSocket *s, const Anope::string &target, int port);
00177 
00182         virtual SocketFlag FinishConnect(ConnectionSocket *s);
00183 
00186         virtual void Destroy() { }
00187 };
00188 
00189 class CoreExport Socket
00190 {
00191  protected:
00192         /* Socket FD */
00193         int sock;
00194         /* Is this an IPv6 socket? */
00195         bool ipv6;
00196 
00197  public:
00198         std::bitset<SF_SIZE> flags;
00199 
00200         /* Sockaddrs for bind() (if it's bound) */
00201         sockaddrs bindaddr;
00202 
00203         /* I/O functions used for this socket */
00204         SocketIO *io;
00205 
00208         Socket();
00209 
00215         Socket(int sock, bool ipv6 = false, int type = SOCK_STREAM);
00216 
00219         virtual ~Socket();
00220 
00224         int GetFD() const;
00225 
00229         bool IsIPv6() const;
00230 
00235         bool SetBlocking(bool state);
00236 
00241         void Bind(const Anope::string &ip, int port = 0);
00242 
00246         virtual bool Process();
00247 
00251         virtual bool ProcessRead();
00252 
00256         virtual bool ProcessWrite();
00257 
00261         virtual void ProcessError();
00262 };
00263 
00264 class CoreExport BufferedSocket : public virtual Socket
00265 {
00266  protected:
00267         /* Things read from the socket */
00268         Anope::string read_buffer;
00269         /* Things to be written to the socket */
00270         Anope::string write_buffer;
00271         /* How much data was received from this socket on this recv() */
00272         int recv_len;
00273 
00274  public:
00275         BufferedSocket();
00276         virtual ~BufferedSocket();
00277 
00281         bool ProcessRead() anope_override;
00282 
00286         bool ProcessWrite() anope_override;
00287 
00290         const Anope::string GetLine();
00291 
00295  protected:
00296         virtual void Write(const char *buffer, size_t l);
00297  public:
00298         void Write(const char *message, ...);
00299         void Write(const Anope::string &message);
00300 
00304         int ReadBufferLen() const;
00305 
00309         int WriteBufferLen() const;
00310 };
00311 
00312 class CoreExport BinarySocket : public virtual Socket
00313 {
00314  protected:
00315         struct DataBlock
00316         {
00317                 char *orig;
00318                 char *buf;
00319                 size_t len;
00320 
00321                 DataBlock(const char *b, size_t l);
00322                 ~DataBlock();
00323         };
00324 
00325         /* Data to be written out */
00326         std::deque<DataBlock *> write_buffer;
00327 
00328  public:
00329         BinarySocket();
00330         virtual ~BinarySocket();
00331 
00335         bool ProcessRead() anope_override;
00336 
00340         bool ProcessWrite() anope_override;
00341 
00346         virtual void Write(const char *buffer, size_t l);
00347         void Write(const char *message, ...);
00348         void Write(const Anope::string &message);
00349 
00355         virtual bool Read(const char *buffer, size_t l);
00356 };
00357 
00358 class CoreExport ListenSocket : public virtual Socket
00359 {
00360  public:
00366         ListenSocket(const Anope::string &bindip, int port, bool ipv6);
00367         virtual ~ListenSocket();
00368 
00372         bool ProcessRead();
00373 
00379         virtual ClientSocket *OnAccept(int fd, const sockaddrs &addr) = 0;
00380 };
00381 
00382 class CoreExport ConnectionSocket : public virtual Socket
00383 {
00384  public:
00385         /* Sockaddrs for connection ip/port */
00386         sockaddrs conaddr;
00387 
00390         ConnectionSocket();
00391 
00396         void Connect(const Anope::string &TargetHost, int Port);
00397 
00402         bool Process() anope_override;
00403 
00407         void ProcessError() anope_override;
00408 
00411         virtual void OnConnect();
00412 
00416         virtual void OnError(const Anope::string &error);
00417 };
00418 
00419 class CoreExport ClientSocket : public virtual Socket
00420 {
00421  public:
00422         /* Listen socket this connection came from */
00423         ListenSocket *ls;
00424         /* Clients address */
00425         sockaddrs clientaddr;
00426 
00431         ClientSocket(ListenSocket *ls, const sockaddrs &addr);
00432 
00437         bool Process() anope_override;
00438 
00442         void ProcessError() anope_override;
00443 
00446         virtual void OnAccept();
00447 
00450         virtual void OnError(const Anope::string &error);
00451 };
00452 
00453 class CoreExport Pipe : public Socket
00454 {
00455  public:
00459         int write_pipe;
00460 
00461         Pipe();
00462         ~Pipe();
00463 
00466         bool ProcessRead() anope_override;
00467 
00472         void Write(const char *data, size_t sz);
00473         inline void Write(const Anope::string &data) { this->Write(data.c_str(), data.length() + 1); }
00474 
00480         int Read(char *data, size_t sz);
00481 
00486         bool SetWriteBlocking(bool state);
00487 
00491         void Notify();
00492 
00495         virtual void OnNotify() = 0;
00496 };
00497 
00498 extern CoreExport uint32_t TotalRead;
00499 extern CoreExport uint32_t TotalWritten;
00500 extern CoreExport SocketIO NormalSocketIO;
00501 
00502 #endif // SOCKET_H