]> git.tdb.fi Git - libs/net.git/commitdiff
Hide platform specific parts of socket addresses
authorMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 16:23:26 +0000 (19:23 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 6 Aug 2011 16:23:26 +0000 (19:23 +0300)
12 files changed:
source/datagramsocket.cpp
source/inet.cpp
source/inet.h
source/inet6.cpp
source/inet6.h
source/resolve.cpp
source/sockaddr.cpp
source/sockaddr.h
source/sockaddr_private.h [new file with mode: 0644]
source/socket.cpp
source/streamlistensocket.cpp
source/streamsocket.cpp

index 7aee3f868d455429c575f77f0d93cf817aaa860f..3f20ba5e242a49f39d47731e97d04ab1674a75e2 100644 (file)
@@ -3,6 +3,7 @@
 #include <msp/io/handle_private.h>
 #include <msp/strings/format.h>
 #include "datagramsocket.h"
+#include "sockaddr_private.h"
 #include "socket_private.h"
 
 namespace Msp {
@@ -19,10 +20,9 @@ DatagramSocket::DatagramSocket(Family f, int p):
 
 int DatagramSocket::connect(const SockAddr &addr)
 {
-       sockaddr_storage sa;
-       socklen_t size = addr.fill_sockaddr(sa);
+       SockAddr::SysAddr sa = addr.to_sys();
 
-       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
        if(err==-1)
        {
 #ifdef WIN32
@@ -36,24 +36,23 @@ int DatagramSocket::connect(const SockAddr &addr)
        peer_addr = addr.copy();
 
        delete local_addr;
-       size = sizeof(sockaddr_storage);
-       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
-       local_addr = SockAddr::create(sa);
+       SockAddr::SysAddr lsa;
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
+       local_addr = SockAddr::from_sys(lsa);
 
        connected = true;
 
        return (err==0)?0:1;
 }
 
-unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &addr_)
+unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &addr)
 {
        if(size==0)
                return 0;
 
-       sockaddr_storage addr;
-       socklen_t addr_len = addr_.fill_sockaddr(addr);
+       SockAddr::SysAddr sa = addr.to_sys();
 
-       int ret = ::sendto(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), addr_len);
+       int ret = ::sendto(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
        if(ret<0)
        {
                if(errno==EAGAIN)
@@ -71,15 +70,13 @@ unsigned DatagramSocket::sendto(const char *buf, unsigned size, const SockAddr &
        return ret;
 }
 
-unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&addr_)
+unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&from_addr)
 {
        if(size==0)
                return 0;
 
-       sockaddr_storage addr;
-       socklen_t addr_len = sizeof(sockaddr_storage);
-
-       int ret = ::recvfrom(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&addr), &addr_len);
+       SockAddr::SysAddr sa;
+       int ret = ::recvfrom(priv->handle, buf, size, 0, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
        if(ret<0)
        {
                if(errno==EAGAIN)
@@ -94,7 +91,7 @@ unsigned DatagramSocket::recvfrom(char *buf, unsigned size, SockAddr *&addr_)
                }
        }
 
-       addr_ = SockAddr::create(addr);
+       from_addr = SockAddr::from_sys(sa);
 
        return ret;
 }
index 41b5ae7cb0b232d847be91054e07e05319dfd397..29e24aa7836d6843652da740fb47de576e8db387 100644 (file)
@@ -1,5 +1,11 @@
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
 #include <msp/strings/format.h>
 #include "inet.h"
+#include "sockaddr_private.h"
 
 using namespace std;
 
@@ -7,37 +13,39 @@ namespace Msp {
 namespace Net {
 
 InetAddr::InetAddr():
-       addr(0),
        port(0)
-{ }
-
-InetAddr::InetAddr(const sockaddr_in &sa):
-       addr(sa.sin_addr.s_addr),
-       port(sa.sin_port)
-{ }
-
-InetAddr::InetAddr(in_addr_t a, in_port_t p):
-       addr(htonl(a)),
-       port(htons(p))
-{ }
+{
+       fill(addr, addr+4, 0);
+}
 
-string InetAddr::str() const
+InetAddr::InetAddr(const SysAddr &sa)
 {
-       const unsigned char *ptr = reinterpret_cast<const unsigned char *>(&addr);
-       string result = format("%d.%d.%d.%d", ptr[0], ptr[1], ptr[2], ptr[3]);
-       if(port)
-               result += format(":%d", ntohs(port));
-       return result;
+       const sockaddr_in &sai = reinterpret_cast<const sockaddr_in &>(sa.addr);
+       addr[0] = sai.sin_addr.s_addr>>24;
+       addr[1] = sai.sin_addr.s_addr>>16;
+       addr[2] = sai.sin_addr.s_addr>>8;
+       addr[3] = sai.sin_addr.s_addr;
+       port = ntohs(sai.sin_port);
 }
 
-unsigned InetAddr::fill_sockaddr(sockaddr &sa) const
+SockAddr::SysAddr InetAddr::to_sys() const
 {
-       sockaddr_in &sai = reinterpret_cast<sockaddr_in &>(sa);
+       SysAddr sa;
+       sa.size = sizeof(sockaddr_in);
+       sockaddr_in &sai = reinterpret_cast<sockaddr_in &>(sa.addr);
        sai.sin_family = AF_INET;
-       sai.sin_addr.s_addr = addr;
-       sai.sin_port = port;
+       sai.sin_addr.s_addr = (addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | (addr[3]);
+       sai.sin_port = htons(port);
 
-       return sizeof(sockaddr_in);
+       return sa;
+}
+
+string InetAddr::str() const
+{
+       string result = format("%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
+       if(port)
+               result += format(":%d", port);
+       return result;
 }
 
 } // namespace Net
index 75735a7f36e1cf3e536dadf0b6d4915e26cb1fcd..94436f9c877873aceaa1b3a21aa822ff4f779b29 100644 (file)
@@ -1,11 +1,6 @@
 #ifndef MSP_NET_INET_H_
 #define MSP_NET_INET_H_
 
-#ifdef WIN32
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
 #include "sockaddr.h"
 
 namespace Msp {
@@ -17,26 +12,19 @@ Address class for IPv4 sockets.
 class InetAddr: public SockAddr
 {
 private:
-#ifdef WIN32
-       typedef u_long in_addr_t;
-       typedef u_short in_port_t;
-#endif
-
-       in_addr_t addr;
-       in_port_t port;
+       unsigned char addr[4];
+       unsigned port;
 
 public:
        InetAddr();
-       InetAddr(const sockaddr_in &);
-       InetAddr(in_addr_t, in_port_t);
+       InetAddr(const SysAddr &);
 
        virtual InetAddr *copy() const { return new InetAddr(*this); }
 
+       virtual SysAddr to_sys() const;
+
        Family get_family() const { return INET; }
-       in_addr_t get_addr() const { return ntohl(addr); }
-       in_port_t get_port() const { return ntohs(port); }
        std::string str() const;
-       virtual unsigned fill_sockaddr(sockaddr &) const;
 };
 
 } // namespace Net
index 6903a778d2998f56e03d851c7c6ba830346c7a96..79da1d2269316e2ab0931f738b2fd160f6d3b773 100644 (file)
@@ -1,5 +1,12 @@
+#ifdef WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#else
+#include <netinet/in.h>
+#endif
 #include <msp/strings/format.h>
 #include "inet6.h"
+#include "sockaddr_private.h"
 
 using namespace std;
 
@@ -7,19 +14,30 @@ namespace Msp {
 namespace Net {
 
 Inet6Addr::Inet6Addr():
-       addr(in6addr_any),
        port(0)
-{ }
+{
+       fill(addr, addr+16, 0);
+}
 
-Inet6Addr::Inet6Addr(const sockaddr_in6 &sai6):
-       addr(sai6.sin6_addr),
-       port(sai6.sin6_port)
-{ }
+Inet6Addr::Inet6Addr(const SysAddr &sa)
+{
+       const sockaddr_in6 &sai6 = reinterpret_cast<const sockaddr_in6 &>(sa.addr);
+       std::copy(sai6.sin6_addr.s6_addr, sai6.sin6_addr.s6_addr+16, addr);
+       port = htons(sai6.sin6_port);
+}
 
-Inet6Addr::Inet6Addr(unsigned char a[16], in_port_t p):
-       port(p)
+SockAddr::SysAddr Inet6Addr::to_sys() const
 {
-       std::copy(a, a+16, addr.s6_addr);
+       SysAddr sa;
+       sa.size = sizeof(sockaddr_in6);
+       sockaddr_in6 &sai6 = reinterpret_cast<sockaddr_in6 &>(sa.addr);
+       sai6.sin6_family = AF_INET6;
+       std::copy(addr, addr+16, sai6.sin6_addr.s6_addr);
+       sai6.sin6_port = htons(port);
+       sai6.sin6_flowinfo = 0;
+       sai6.sin6_scope_id = 0;
+
+       return sa;
 }
 
 string Inet6Addr::str() const
@@ -27,34 +45,17 @@ string Inet6Addr::str() const
        string result = "[";
        for(unsigned i=0; i<16; i+=2)
        {
-               unsigned short part = (addr.s6_addr[i]<<8) | addr.s6_addr[i+1];
+               unsigned short part = (addr[i]<<8) | addr[i+1];
                if(i>0)
                        result += ':';
                result += format("%x", part);
        }
        result += ']';
        if(port)
-               result += format(":%d", ntohs(port));
+               result += format(":%d", port);
 
        return result;
 }
 
-unsigned Inet6Addr::fill_sockaddr(sockaddr &) const
-{
-       throw logic_error("sizeof(sockaddr_in6)>sizeof(sockaddr)");
-}
-
-unsigned Inet6Addr::fill_sockaddr(sockaddr_storage &sa) const
-{
-       sockaddr_in6 &sai6 = reinterpret_cast<sockaddr_in6 &>(sa);
-       sai6.sin6_family = AF_INET6;
-       sai6.sin6_port = port;
-       sai6.sin6_addr = addr;
-       sai6.sin6_flowinfo = 0;
-       sai6.sin6_scope_id = 0;
-
-       return sizeof(sockaddr_in6);
-}
-
 } // namespace Net
 } // namespace Msp
index f5a7079af2b55eaee5e0132167c84769d6e72d37..97197c735593a2d287d0d1f12d313bc60bf75650 100644 (file)
@@ -1,12 +1,6 @@
 #ifndef MSP_NET_INET6_H_
 #define NSP_NET_INET6_H_
 
-#ifdef WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else
-#include <netinet/in.h>
-#endif
 #include "sockaddr.h"
 
 namespace Msp {
@@ -15,25 +9,19 @@ namespace Net {
 class Inet6Addr: public SockAddr
 {
 private:
-#ifdef WIN32
-       typedef u_short in_port_t;
-#endif
-
-       in6_addr addr;
-       in_port_t port;
+       unsigned char addr[16];
+       unsigned port;
 
 public:
        Inet6Addr();
-       Inet6Addr(const sockaddr_in6 &);
-       Inet6Addr(unsigned char [16], in_port_t);
+       Inet6Addr(const SysAddr &);
 
        virtual Inet6Addr *copy() const { return new Inet6Addr(*this); }
 
+       virtual SysAddr to_sys() const;
+
        virtual Family get_family() const { return INET6; }
        virtual std::string str() const;
-
-       virtual unsigned fill_sockaddr(sockaddr &) const;
-       virtual unsigned fill_sockaddr(sockaddr_storage &) const;
 };
 
 } // namespace Net
index 3896db7a81a5d1c0a3be8ccef6667947e4b814f5..076fea065dee3960abc755d03e816d9fbcac909a 100644 (file)
@@ -6,6 +6,7 @@
 #endif
 #include <msp/core/systemerror.h>
 #include <msp/strings/format.h>
+#include "sockaddr_private.h"
 #include "socket.h"
 #include "resolve.h"
 
@@ -44,7 +45,12 @@ SockAddr *resolve(const string &s, Family family)
        int err = getaddrinfo(chost, cserv, &hints, &res);
        if(err==0)
        {
-               SockAddr *addr = SockAddr::create(*res->ai_addr);
+               SockAddr::SysAddr sa;
+               sa.size = res->ai_addrlen;
+               const char *sptr = reinterpret_cast<const char *>(res->ai_addr);
+               char *dptr = reinterpret_cast<char *>(&sa.addr);
+               copy(sptr, sptr+res->ai_addrlen, dptr);
+               SockAddr *addr = SockAddr::from_sys(sa);
                freeaddrinfo(res);
                return addr;
        }
index f6123ca38c685e9b3631593bdd9e89b4de248587..0d14dfd34cb6899b30c60926b272c9cc85b36aa5 100644 (file)
@@ -1,28 +1,30 @@
 #include <stdexcept>
 #include "inet.h"
 #include "inet6.h"
+#include "sockaddr_private.h"
 
 using namespace std;
 
 namespace Msp {
 namespace Net {
 
-SockAddr *SockAddr::create(const sockaddr_storage &sa)
+SockAddr *SockAddr::from_sys(const SysAddr &sa)
 {
-       switch(sa.ss_family)
+       switch(sa.addr.ss_family)
        {
        case AF_INET:
-               return new InetAddr(reinterpret_cast<const sockaddr_in &>(sa));
+               return new InetAddr(sa);
        case AF_INET6:
-               return new Inet6Addr(reinterpret_cast<const sockaddr_in6 &>(sa));
+               return new Inet6Addr(sa);
        default:
                throw invalid_argument("SockAddr::create");
        }
 }
 
-unsigned SockAddr::fill_sockaddr(sockaddr_storage &sa) const
+SockAddr::SysAddr::SysAddr():
+       size(sizeof(sockaddr_storage))
 {
-       return fill_sockaddr(reinterpret_cast<sockaddr &>(sa));
+       addr.ss_family = AF_UNSPEC;
 }
 
 } // namespace Net
index ff2f88a9b7be650064d4528f18ba3ff88ddd510e..bf7547778dbf80cca68f85d2117bf8c74fbf2204 100644 (file)
@@ -2,9 +2,6 @@
 #define MSP_NET_SOCKADDR_H_
 
 #include <string>
-#ifndef WIN32
-#include <sys/socket.h>
-#endif
 #include "constants.h"
 
 namespace Msp {
@@ -12,23 +9,21 @@ namespace Net {
 
 class SockAddr
 {
+public:
+       struct SysAddr;
+
 protected:
        SockAddr() { }
 public:
        virtual ~SockAddr() { }
 
-       static SockAddr *create(const sockaddr &sa) { return create(reinterpret_cast<const sockaddr_storage &>(sa)); }
-       static SockAddr *create(const sockaddr_storage &);
-
        virtual SockAddr *copy() const = 0;
 
+       static SockAddr *from_sys(const SysAddr &);
+       virtual SysAddr to_sys() const = 0;
+
        virtual Family get_family() const = 0;
        virtual std::string str() const = 0;
-
-       /** Fills a struct sockaddr with information from this SockAddr.  Returns
-       the number of bytes used. */
-       virtual unsigned fill_sockaddr(sockaddr &) const = 0;
-       virtual unsigned fill_sockaddr(sockaddr_storage &) const;
 };
 
 } // namespace Net
diff --git a/source/sockaddr_private.h b/source/sockaddr_private.h
new file mode 100644 (file)
index 0000000..16af063
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef MSP_NET_SOCKADDR_PRIVATE_H_
+#define MSP_NET_SOCKADDR_PRIVATE_H_
+
+#ifdef WIN32
+#include <winsock2.h>
+#else
+#include <sys/socket.h>
+#endif
+#include "sockaddr.h"
+
+namespace Msp {
+namespace Net {
+
+struct SockAddr::SysAddr
+{
+       struct sockaddr_storage addr;
+#ifdef WIN32
+       int size;
+#else
+       socklen_t size;
+#endif
+
+       SysAddr();
+};
+
+} // namespace Net
+} // namespace Msp
+
+#endif
index 8fa910cbd5a97eb52479a0e18192f18a6425633b..0e2950930f0e653d7348bcff826d3b0d53fcb57c 100644 (file)
@@ -9,6 +9,7 @@
 #include <msp/strings/format.h>
 #include <msp/time/rawtime_private.h>
 #include <msp/time/units.h>
+#include "sockaddr_private.h"
 #include "socket.h"
 #include "socket_private.h"
 
@@ -48,10 +49,9 @@ Socket::Socket(const Private &p, const SockAddr &paddr):
 {
        priv->handle = p.handle;
 
-       sockaddr_storage sa;
-       socklen_t size = sizeof(sockaddr_storage);
-       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
-       local_addr = SockAddr::create(sa);
+       SockAddr::SysAddr sa;
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
+       local_addr = SockAddr::from_sys(sa);
 
 #ifdef WIN32
        *priv->event = CreateEvent(0, false, false, 0);
@@ -113,10 +113,9 @@ const IO::Handle &Socket::get_event_handle()
 
 void Socket::bind(const SockAddr &addr)
 {
-       sockaddr_storage sa;
-       unsigned size = addr.fill_sockaddr(sa);
+       SockAddr::SysAddr sa = addr.to_sys();
 
-       int err = ::bind(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::bind(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
        if(err==-1)
                throw system_error("bind");
 
index 3b375bcafcadb54d0581b1cf6500b82a87ca1448..681adeddb8ab95957b5eab200b718f8f3298e9a3 100644 (file)
@@ -3,6 +3,7 @@
 #include <msp/core/systemerror.h>
 #include <msp/io/handle_private.h>
 #include <msp/strings/format.h>
+#include "sockaddr_private.h"
 #include "socket_private.h"
 #include "streamlistensocket.h"
 #include "streamsocket.h"
@@ -44,12 +45,11 @@ StreamSocket *StreamListenSocket::accept()
        if(!listening)
                throw bad_socket_state("not listening");
 
-       sockaddr_storage sa;
-       socklen_t size = sizeof(sockaddr_storage);
+       SockAddr::SysAddr sa;
        Private new_p;
-       new_p.handle = ::accept(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
+       new_p.handle = ::accept(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), &sa.size);
 
-       RefPtr<SockAddr> paddr = SockAddr::create(sa);
+       RefPtr<SockAddr> paddr = SockAddr::from_sys(sa);
        return new StreamSocket(new_p, *paddr);
 }
 
index c6cd214e18dc08dc1620cd190f27287dd8c6ce11..5794ecd82914b16c3c8d22c7edc28a56ffffcbf5 100644 (file)
@@ -6,6 +6,7 @@
 #include <msp/io/handle_private.h>
 #include <msp/io/poll.h>
 #include <msp/strings/format.h>
+#include "sockaddr_private.h"
 #include "socket_private.h"
 #include "streamsocket.h"
 
@@ -75,11 +76,10 @@ int StreamSocket::connect(const SockAddr &addr)
        if(connected)
                throw bad_socket_state("already connected");
 
-       sockaddr_storage sa;
-       socklen_t size = addr.fill_sockaddr(sa);
+       SockAddr::SysAddr sa = addr.to_sys();
 
 #ifdef WIN32
-       int err = WSAConnect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size, 0, 0, 0, 0);
+       int err = WSAConnect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size, 0, 0, 0, 0);
        if(err==SOCKET_ERROR)
        {
                int err_code = WSAGetLastError();
@@ -93,7 +93,7 @@ int StreamSocket::connect(const SockAddr &addr)
                        throw system_error("connect", err_code);
        }
 #else
-       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa), size);
+       int err = ::connect(priv->handle, reinterpret_cast<sockaddr *>(&sa.addr), sa.size);
        if(err==-1)
        {
                if(errno==EINPROGRESS)
@@ -110,9 +110,9 @@ int StreamSocket::connect(const SockAddr &addr)
        peer_addr = addr.copy();
 
        delete local_addr;
-       size = sizeof(sockaddr_storage);
-       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&sa), &size);
-       local_addr = SockAddr::create(sa);
+       SockAddr::SysAddr lsa;
+       getsockname(priv->handle, reinterpret_cast<sockaddr *>(&lsa.addr), &lsa.size);
+       local_addr = SockAddr::from_sys(lsa);
 
        if(err==0)
        {