]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Socket.hh
socket and packet copying
[chaz/yoink] / src / Moof / Socket.hh
index c53ca06289974869f8d1b31fe438605aea827835..948f9423785ea944087f29e580b5ef5b4f6f4391 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef _MOOF_SOCKET_HH_
 #define _MOOF_SOCKET_HH_
 
+#include <algorithm>
 #include <cstring>
 #include <sstream>
 #include <string>
@@ -54,8 +55,8 @@ public:
                mSize(0),
                mType(0)
        {
-               mAddress.sa.sa_family = AF_UNSPEC;
-               mAddress.v4.sin_port = 0;
+               mAddr.sa.sa_family = AF_UNSPEC;
+               mAddr.in.sin_port = 0;
        }
 
        SocketAddress(const std::string& service, const std::string& name,
@@ -73,7 +74,7 @@ public:
        SocketAddress(const struct addrinfo* addr, const std::string& name)
        {
                mType = addr->ai_socktype;
-               memcpy(&mAddress.sa, addr->ai_addr, addr->ai_addrlen);
+               memcpy(&mAddr.sa, addr->ai_addr, addr->ai_addrlen);
                mName = name;
                mSize = addr->ai_addrlen;
        }
@@ -82,7 +83,7 @@ public:
                        int type = SOCK_STREAM)
        {
                mType = type;
-               memcpy(&mAddress.sa, addr, size);
+               memcpy(&mAddr.sa, addr, size);
                mSize = size;
                setNameFromAddress();
        }
@@ -121,7 +122,7 @@ public:
                if (status == 0)
                {
                        mType = addr->ai_socktype;
-                       memcpy(&mAddress.sa, addr->ai_addr, addr->ai_addrlen);
+                       memcpy(&mAddr.sa, addr->ai_addr, addr->ai_addrlen);
                        mSize = addr->ai_addrlen;
 
                        if (name != "") mName = name;
@@ -134,8 +135,8 @@ public:
                        Mf::logWarning(gai_strerror(status));
                        mType = 0;
                        mSize = 0;
-                       mAddress.sa.sa_family = AF_UNSPEC;
-                       mAddress.v4.sin_port = 0;
+                       mAddr.sa.sa_family = AF_UNSPEC;
+                       mAddr.in.sin_port = 0;
                }
        }
 
@@ -158,7 +159,7 @@ public:
 
        unsigned short port() const
        {
-               return ntohs(mAddress.v4.sin_port);
+               return ntohs(mAddr.in.sin_port);
        }
 
        int type() const
@@ -168,13 +169,13 @@ public:
 
        int family() const
        {
-               return mAddress.sa.sa_family;
+               return mAddr.sa.sa_family;
        }
 
 
        const struct sockaddr* address() const
        {
-               return mSize != 0 ? &mAddress.sa : 0;
+               return mSize != 0 ? &mAddr.sa : 0;
        }
 
        size_t size() const
@@ -226,10 +227,10 @@ private:
        {
 #if defined(_WIN32)
                // inet_ntop was introduced in Vista
-               mName = inet_ntoa(mAddress.v4.sin_addr);
+               mName = inet_ntoa(mAddr.in.sin_addr);
 #else
                char name[INET6_ADDRSTRLEN] = {'\0'};
-               inet_ntop(mAddress.sa.sa_family, &mAddress.sa, name, sizeof(name));
+               inet_ntop(mAddr.sa.sa_family, &mAddr.sa, name, sizeof(name));
                mName = name;
 #endif
        }
@@ -238,10 +239,9 @@ private:
        union
        {
                sockaddr                        sa;
-               sockaddr_in                     v4;
-               sockaddr_in6            v6;
+               sockaddr_in                     in;
                sockaddr_storage        storage;
-       }                       mAddress;
+       }                       mAddr;
        size_t          mSize;
        std::string     mName;
        int                     mType;
@@ -250,16 +250,92 @@ private:
 
 class Socket
 {
+       struct Impl
+       {
+               int                             fd;
+               bool                    isConnected;
+               SocketAddress   address;
+       };
+
+
 public:
 
+       Socket() :
+               mFd(-1),
+               mIsConnected(false) {}
+
        Socket(const SocketAddress& address) :
                mFd(-1),
                mIsConnected(false),
-               mAddress(address)
+               mAddress(address) {}
+
+       Socket(const std::string& service, const std::string& name,
+                       int type = SOCK_STREAM, int family = AF_UNSPEC) :
+               mFd(-1),
+               mIsConnected(false),
+               mAddress(SocketAddress(service, name, type, family)) {}
+
+       Socket(const std::string& service,
+                       int type = SOCK_STREAM, int family = AF_UNSPEC) :
+               mFd(-1),
+               mIsConnected(false),
+               mAddress(SocketAddress(service, type, family)) {}
+
+
+       Socket(Socket& move) :
+               mFd(move.mFd),
+               mIsConnected(move.mIsConnected),
+               mAddress(move.mAddress)
+       {
+               move.mFd = -1;
+               move.mIsConnected = false;
+       }
+
+       Socket(Impl move) :
+               mFd(move.fd),
+               mIsConnected(move.isConnected),
+               mAddress(move.address) {}
+
+       Socket& operator=(Socket& move)
+       {
+#if defined(_WIN32)
+               if (mFd != -1) closesocket(mFd);
+#else
+               if (mFd != -1) close(mFd);
+#endif
+               mFd = move.mFd;
+               mIsConnected = move.mIsConnected;
+               mAddress = move.mAddress;
+               move.mFd = -1;
+               move.mIsConnected = false;
+               return *this;
+       }
+
+       Socket& operator=(Impl move)
+       {
+#if defined(_WIN32)
+               if (mFd != -1) closesocket(mFd);
+#else
+               if (mFd != -1) close(mFd);
+#endif
+               mFd = move.fd;
+               mIsConnected = move.isConnected;
+               mAddress = move.address;
+               return *this;
+       }
+
+       operator Impl()
        {
-               mFd = socket(address.family(), address.type(), 0);
+               Impl impl;
+               impl.fd = mFd;
+               impl.isConnected = mIsConnected;
+               impl.address = mAddress;
+               mFd = -1;
+               mIsConnected = false;
+               return impl;
        }
 
+
        ~Socket()
        {
 #if defined(_WIN32)
@@ -283,6 +359,7 @@ public:
 
        int connect()
        {
+               if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0);
                int result = ::connect(mFd, mAddress.address(), mAddress.size());
                mIsConnected = result != -1;
                return result;
@@ -290,6 +367,7 @@ public:
 
        int bind()
        {
+               if (mFd == -1) mFd = socket(mAddress.family(), mAddress.type(), 0);
                return ::bind(mFd, mAddress.address(), mAddress.size());
        }
 
@@ -298,9 +376,15 @@ public:
                return ::listen(mFd, backlog > 0 ? backlog : SOMAXCONN);
        }
 
-       Socket accept()
+       int accept(Socket& socket)
        {
-               return Socket(mFd);
+               Socket temp = Socket(mFd);
+               if (temp.mFd != -1)
+               {
+                       socket = temp;
+                       return socket.mFd;
+               }
+               return -1;
        }
 
 
@@ -423,7 +507,11 @@ private:
                socklen_t length = sizeof(addr);
 
                mFd = ::accept(fd, &addr.sa, &length);
-               mAddress = SocketAddress(&addr.sa, length);
+               if (mFd != -1)
+               {
+                       mIsConnected = true;
+                       mAddress = SocketAddress(&addr.sa, length);
+               }
        }
 
 
This page took 0.024877 seconds and 4 git commands to generate.