]> git.llucax.com Git - software/posixx.git/commitdiff
Improve internet addresses (inet::sockaddr)
authorLeandro Lucarella <llucarella@integratech.com.ar>
Thu, 22 Jan 2009 19:51:53 +0000 (17:51 -0200)
committerLeandro Lucarella <llucarella@integratech.com.ar>
Mon, 9 Feb 2009 12:27:37 +0000 (10:27 -0200)
This patch improves the internet addresses. It adds a new constructor (to
create an address from a string), setters and getters to handle byte
ordering better and a couple of address constants (any and broadcast).

New test cases are created too.

src/socket/inet.hpp
src/socket/inet/print.hpp
test/socket/inet/common.hpp
test/socket/inet/sockaddr.cpp

index 1ad2ce49a7d6cdb1a6cc8cb59edb612ba6a376d1..f86246fc91f6561a7b39e7b35ffe3b24404a7dcc 100644 (file)
@@ -15,27 +15,81 @@ namespace posixx { namespace socket {
 /// Internet Protocol sockets
 namespace inet {
 
+
+/// Address to accept any incoming messages
+const uint32_t any = INADDR_ANY;
+
+/// Address to send to all hosts
+const uint32_t broadcast = INADDR_BROADCAST;
+
+
 /// IP socket address
 struct sockaddr: sockaddr_in
 {
 
        /**
         * Create an IP socket address.
+        *
+        * @note The IP address is expected in network byte order but the
+        *       port is expected in host byte order. This is because this
+        *       constructor is expected to be used with predefined IP
+        *       addresses, like any, none, loopback, etc.
+        *
+        * @param addr IP address in network byte order
+        * @param port IP port in host byte order
+        *
+        * @see any, none, etc. constants
         */
-       sockaddr(u_int16_t port = 0, const std::string& ip = "0.0.0.0")
-                       throw ();
+       explicit sockaddr(uint32_t addr = any, uint16_t port = 0) throw ();
 
-       /// Length of this IP socket address
-       socklen_t length() const throw ();
+       /**
+        * Create an IP socket address.
+        *
+        * @param addr String representation of the IP address
+        * @param port IP port in host byte order
+        */
+       explicit sockaddr(const std::string& addr, uint16_t port) throw ();
 
-       /// Compare two IP socket addresses
-       bool operator == (const sockaddr& other) const throw ();
+       /**
+        * Set the IP address and port.
+        *
+        * @param addr IP address in network byte order
+        * @param port IP port in host byte order
+        *
+        * @see sockaddr(uint32_t, uint16_t)
+        */
+       void set(uint32_t addr, uint16_t port) throw();
+
+       /**
+        * Set the IP address and port.
+        *
+        * @param addr String representation of the IP address
+        * @param port IP port in host byte order
+        *
+        * @see sockaddr(const std::string&, uint16_t)
+        */
+       void set(const std::string& addr, uint16_t port) throw();
+
+       /// Get the IP address as a string
+       std::string addr() const throw ();
+
+       /// Set the IP address (in network byte order)
+       void addr(uint32_t addr) throw ();
+
+       /// Set the IP address from a string
+       void addr(const std::string& addr) throw ();
 
        /// Get the port number
        uint16_t port() const throw ();
 
-       /// Get the IP address
-       std::string addr() const throw ();
+       /// Set the port number (port is expected to be in host byte order)
+       void port(uint16_t port) throw ();
+
+       /// Length of this IP socket address
+       socklen_t length() const throw ();
+
+       /// Compare two IP socket addresses
+       bool operator == (const sockaddr& other) const throw ();
 
 }; // struct sockaddr
 
@@ -57,37 +111,37 @@ typedef posixx::socket::basic_socket< traits > socket;
 
 
 inline
-posixx::socket::inet::sockaddr::sockaddr(u_int16_t port, const std::string& ip)
+posixx::socket::inet::sockaddr::sockaddr(uint32_t addr, uint16_t port)
                throw ()
 {
        memset(this, 0, sizeof(struct sockaddr_in));
        sin_family = AF_INET;
-       if (ip == "0.0.0.0") {
-               sin_addr.s_addr = htonl(INADDR_ANY);
-       }
-       else {
-               sin_addr.s_addr = inet_addr(ip.c_str());
-       }
-       sin_port = htons(port);
+       set(addr, port);
 }
 
 inline
-socklen_t posixx::socket::inet::sockaddr::length() const throw ()
+posixx::socket::inet::sockaddr::sockaddr(const std::string& addr, uint16_t port)
+               throw ()
 {
-       return sizeof(sockaddr_in);
+       memset(this, 0, sizeof(struct sockaddr_in));
+       sin_family = AF_INET;
+       set(addr, port);
 }
 
 inline
-bool posixx::socket::inet::sockaddr::operator == (const sockaddr& other) const
+void posixx::socket::inet::sockaddr::set(uint32_t addr, uint16_t port)
                throw ()
 {
-       return !memcmp(this, &other, sizeof(*this));
+       sin_addr.s_addr = addr;
+       this->port(port);
 }
 
 inline
-uint16_t posixx::socket::inet::sockaddr::port() const throw ()
+void posixx::socket::inet::sockaddr::set(const std::string& addr, uint16_t port)
+               throw ()
 {
-       return ntohs(sin_port);
+       this->addr(addr);
+       this->port(port);
 }
 
 inline
@@ -96,4 +150,41 @@ std::string posixx::socket::inet::sockaddr::addr() const throw ()
        return inet_ntoa(sin_addr);
 }
 
+inline
+void posixx::socket::inet::sockaddr::addr(uint32_t addr) throw ()
+{
+       sin_addr.s_addr = addr;
+}
+
+inline
+void posixx::socket::inet::sockaddr::addr(const std::string& addr) throw ()
+{
+       sin_addr.s_addr = inet_addr(addr.c_str());
+}
+
+inline
+uint16_t posixx::socket::inet::sockaddr::port() const throw ()
+{
+       return ntohs(sin_port);
+}
+
+inline
+void posixx::socket::inet::sockaddr::port(uint16_t port) throw ()
+{
+       sin_port = htons(port);
+}
+
+inline
+socklen_t posixx::socket::inet::sockaddr::length() const throw ()
+{
+       return sizeof(sockaddr_in);
+}
+
+inline
+bool posixx::socket::inet::sockaddr::operator == (const sockaddr& other) const
+               throw ()
+{
+       return !memcmp(this, &other, sizeof(*this));
+}
+
 #endif // POSIXX_SOCKET_INET_HPP_
index 7c61e26f8aa84137552c06af38102cbe881d3bc3..168729a9f78797c093ac9359ccb6eea266a33941 100644 (file)
@@ -8,8 +8,8 @@ inline
 std::ostream& operator << (std::ostream& os,
                const posixx::socket::inet::sockaddr& sa) throw()
 {
-       return os << "inet::sockaddr(port=" << ntohs(sa.sin_port)
-                       << ", addr=" << inet_ntoa(sa.sin_addr) << ")";
+       return os << "inet::sockaddr(addr=" << sa.addr()
+                       << ", port=" << sa.port() << ")";
 }
 
 #endif // POSIXX_SOCKET_INET_PRINT_HPP_
index 9884c7ef0a4ce7b8dddc1704f8b621f5a343f69d..4829557c5aeaad0c8f4854532ee2a0f60d661b81 100644 (file)
@@ -18,7 +18,7 @@ void clean_test_address(posixx::socket::inet::socket& socket,
        socket.opt< posixx::socket::opt::REUSEADDR >(true);
 }
 
-static posixx::socket::inet::sockaddr test_address1(PORT1, IP);
-static posixx::socket::inet::sockaddr test_address2(PORT2, IP);
+static posixx::socket::inet::sockaddr test_address1(IP, PORT1);
+static posixx::socket::inet::sockaddr test_address2(IP, PORT2);
 
 #endif // TEST_SOCKET_IP_COMMON_HPP_
index c7a97aa871c31801f1d3e458e139847e32755bfc..ddda234c3742229270a6622c0897df323557caf2 100644 (file)
@@ -3,9 +3,113 @@
 #include <posixx/socket/inet.hpp> // posixx::socket::inet
 #include <boost/test/unit_test.hpp> // unit testing stuff
 
+namespace inet = posixx::socket::inet;
+
 BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_test )
 {
+       BOOST_CHECK_EQUAL(test_address1.sin_family, AF_INET);
        BOOST_CHECK_EQUAL(test_address1.addr(), IP);
        BOOST_CHECK_EQUAL(test_address1.port(), PORT1);
 }
 
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_default )
+{
+       inet::sockaddr addr;
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::any);
+       BOOST_CHECK_EQUAL(addr.sin_port, 0);
+       BOOST_CHECK_EQUAL(addr.port(), 0);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_broadcast )
+{
+       inet::sockaddr addr(inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.sin_port, 0);
+       BOOST_CHECK_EQUAL(addr.port(), 0);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_broadcast_port )
+{
+       inet::sockaddr addr(inet::broadcast, 12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_1_1_1_1_8080 )
+{
+       inet::sockaddr addr("1.1.1.1", 8080);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.addr(), "1.1.1.1");
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, 0x01010101);
+       BOOST_CHECK_EQUAL(addr.port(), 8080);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_16_16_16_16_12345 )
+{
+       inet::sockaddr addr("16.16.16.16", 12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.addr(), "16.16.16.16");
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, 0x10101010);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_broadcast_port )
+{
+       inet::sockaddr addr;
+       addr.set(inet::broadcast, 12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_16_16_16_16_12345 )
+{
+       inet::sockaddr addr;
+       addr.set("16.16.16.16", 12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.addr(), "16.16.16.16");
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, 0x10101010);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_port_broadcast )
+{
+       inet::sockaddr addr(inet::broadcast);
+       addr.port(12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_port_16_16_16_16_12345 )
+{
+       inet::sockaddr addr("16.16.16.16", 0);
+       addr.port(12345);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.addr(), "16.16.16.16");
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, 0x10101010);
+       BOOST_CHECK_EQUAL(addr.port(), 12345);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_addr_broadcast )
+{
+       inet::sockaddr addr;
+       addr.addr(inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, inet::broadcast);
+       BOOST_CHECK_EQUAL(addr.port(), 0);
+}
+
+BOOST_AUTO_TEST_CASE( socket_inet_sockaddr_set_addr_16_16_16_16 )
+{
+       inet::sockaddr addr;
+       addr.addr("16.16.16.16");
+       BOOST_CHECK_EQUAL(addr.sin_family, AF_INET);
+       BOOST_CHECK_EQUAL(addr.addr(), "16.16.16.16");
+       BOOST_CHECK_EQUAL(addr.sin_addr.s_addr, 0x10101010);
+       BOOST_CHECK_EQUAL(addr.port(), 0);
+}
+