# HG changeset patch # User David Demelier # Date 1467282942 -7200 # Node ID ad302d1b73350ba59fa6e48e3905aedcc7117912 # Parent c79a501782b00076b6361b4b9a9190e114b2b095 Net: Socket is no more a template, use raw addresses instead diff -r c79a501782b0 -r ad302d1b7335 modules/net/net.hpp --- a/modules/net/net.hpp Wed Jun 29 19:18:39 2016 +0200 +++ b/modules/net/net.hpp Thu Jun 30 12:35:42 2016 +0200 @@ -120,7 +120,6 @@ /** * \page net-concepts Concepts * - * - \subpage net-concept-address * - \subpage net-concept-backend * - \subpage net-concept-option * - \subpage net-concept-stream @@ -128,75 +127,6 @@ */ /** - * \page net-concept-address Address (Concept) - * - * An address is used in many places for creating, binding, connecting, receiving and sending. They are implemented as templates to allow - * any type of address and to make sure the same address is used for a given socket. - * - * This concepts requires the following functions: - * - * # Address (constructor) - * - * The address must have the following constructor overloads. - * - * **Note**: the user can add custom constructors. - * - * ## Synopsis - * - * ```` - * Address(); // (0) - * Address(const sockaddr *sa, socklen_t length); // (1) - * ```` - * - * ## Arguments - * - * - **ss**: the storage to construct from, - * - **length**: the storage length. - * - * # domain - * - * Get the domain (e.g. AF_INET). - * - * ## Synopsis - * - * ```` - * int domain() const noexcept; - * ```` - * - * ## Returns - * - * The domain. - * - * # address - * - * Get the underlying address. - * - * ## Synopsis - * - * ```` - * const sockaddr *address() const noexcept; - * ```` - * - * ## Returns - * - * The address. - * - * # length - * - * Get the underlying length. - * - * ## Synopsis - * - * ```` - * socklen_t length() const noexcept; - * ```` - * - * ## Returns - * - * The length. - */ - -/** * \page net-concept-backend Backend (Concept) * * A backend is an interface for the Listener class. It is primarily designed to be the most suitable for the host environment. @@ -300,7 +230,7 @@ * * ```` * template - * void set(Socket
&sc) const; + * void set(Socket &sc) const; * ```` * * ## Arguments @@ -315,7 +245,7 @@ * * ```` * template - * T get(Socket
&sc) const; + * T get(Socket &sc) const; * ```` * * ## Arguments @@ -377,7 +307,7 @@ * ## Synopsis * * ```` - * Socket
accept(); + * Socket accept(); * ```` * * ## Returns @@ -1105,9 +1035,292 @@ } /** + * \brief Generic socket address storage. + * \ingroup net-module-addresses + */ +class Address { +private: + sockaddr_storage m_storage; + socklen_t m_length; + +public: + /** + * Construct empty address. + */ + inline Address() noexcept + : m_storage{} + , m_length(0) + { + } + + /** + * Construct address from existing one. + * + * \pre address != nullptr + * \param address the address + * \param length the address length + */ + inline Address(const sockaddr *address, socklen_t length) noexcept + : m_length(length) + { + assert(address); + + std::memcpy(&m_storage, address, length); + } + + /** + * Get the underlying address. + * + * \return the address + */ + inline const sockaddr *get() const noexcept + { + return reinterpret_cast(&m_storage); + } + + /** + * Overloaded function + * + * \return the address + */ + inline sockaddr *get() noexcept + { + return reinterpret_cast(&m_storage); + } + + /** + * Get the underlying address as the given type (e.g sockaddr_in). + * + * \return the address reference + */ + template + inline const T &as() const noexcept + { + return reinterpret_cast(m_storage); + } + + /** + * Overloaded function + * + * \return the address reference + */ + template + inline T &as() noexcept + { + return reinterpret_cast(m_storage); + } + + /** + * Get the underlying address length. + * + * \return the length + */ + inline socklen_t length() const noexcept + { + return m_length; + } + + /** + * Get the address domain. + * + * \return the domain + */ + inline int domain() const noexcept + { + return m_storage.ss_family; + } +}; + +/** + * \brief Address iterator. + * \ingroup net-module-addresses + * \see resolve + * + * This iterator can be used to try to connect to an host. + * + * When you use resolve with unspecified domain or socket type, the function may retrieve several different addresses that you can + * iterate over to try to connect to. + * + * Example: + * + * ````cpp + * SocketTcp sc; + * AddressIterator end, it = resolve("hostname.test", "80"); + * + * while (!connected_condition && it != end) + * sc.connect(it->address(), it->length()); + * ```` + * + * When an iterator equals to a default constructed iterator, it is considered not dereferenceable. + */ +class AddressIterator : public std::iterator { +private: + std::vector
m_addresses; + std::size_t m_index{0}; + +public: + /** + * Construct a null iterator. + * + * The default constructed iterator is not dereferenceable. + */ + inline AddressIterator() noexcept = default; + + /** + * Construct an address iterator with a set of addresses. + * + * \pre index < m_addresses.size() + * \param addresses the addresses + * \param index the first index + */ + inline AddressIterator(std::vector
addresses, std::size_t index = 0) noexcept + : m_addresses(std::move(addresses)) + , m_index(index) + { + assert(index < m_addresses.size()); + } + + /** + * Get the generic address. + * + * \pre this is dereferenceable + * \return the generic address + */ + inline const Address &operator*() const noexcept + { + assert(m_index <= m_addresses.size()); + + return m_addresses[m_index]; + } + + /** + * Overloaded function. + * + * \pre this is dereferenceable + * \return the generic address + */ + inline Address &operator*() noexcept + { + assert(m_index <= m_addresses.size()); + + return m_addresses[m_index]; + } + + /** + * Get the generic address. + * + * \pre this is dereferenceable + * \return the generic address + */ + inline const Address *operator->() const noexcept + { + assert(m_index <= m_addresses.size()); + + return &m_addresses[m_index]; + } + + /** + * Overloaded function. + * + * \pre this is dereferenceable + * \return the generic address + */ + inline Address *operator->() noexcept + { + assert(m_index <= m_addresses.size()); + + return &m_addresses[m_index]; + } + + /** + * Pre-increment the iterator. + * + * \return this + */ + inline AddressIterator &operator++(int) noexcept + { + if (m_index + 1 >= m_addresses.size()) { + m_addresses.clear(); + m_index = 0; + } else + m_index ++; + + return *this; + } + + /** + * Post-increment the iterator. + * + * \return copy of this + */ + inline AddressIterator operator++() noexcept + { + AddressIterator save = *this; + + if (m_index + 1 >= m_addresses.size()) { + m_addresses.clear(); + m_index = 0; + } else + m_index ++; + + return save; + } + + friend bool operator==(const AddressIterator &, const AddressIterator &) noexcept; + friend bool operator!=(const AddressIterator &, const AddressIterator &) noexcept; +}; + +/** + * Compare two address iterators. + * + * \param i1 the first iterator + * \param i2 the second iterator + * \return true if they equal + */ +inline bool operator==(const AddressIterator &i1, const AddressIterator &i2) noexcept +{ + return i1.m_addresses == i2.m_addresses && i1.m_index == i2.m_index; +} + +/** + * Compare two address iterators. + * + * \param i1 the first iterator + * \param i2 the second iterator + * \return false if they equal + */ +inline bool operator!=(const AddressIterator &i1, const AddressIterator &i2) noexcept +{ + return !(i1 == i2); +} + +/** + * Compare two generic addresses. + * + * \param a1 the first address + * \param a2 the second address + * \return true if they equal + */ +inline bool operator==(const Address &a1, const Address &a2) noexcept +{ + return a1.length() == a2.length() && std::memcmp(a1.get(), a2.get(), a1.length()) == 0; +} + +/** + * Compare two generic addresses. + * + * \param a1 the first address + * \param a2 the second address + * \return false if they equal + */ +inline bool operator!=(const Address &a1, const Address &a2) noexcept +{ + return !(a1 == a2); +} + +/** * \brief Base socket class. */ -template class Socket { protected: /** @@ -1211,7 +1424,7 @@ /** * Object-oriented option setter. * - * The object must have `set(Socket
&) const`. + * The object must have `set(Socket &) const`. * * \pre isOpen() * \param option the option @@ -1253,7 +1466,7 @@ /** * Object-oriented option getter. * - * The object must have `T get(Socket
&) const`, T can be any type and it is the value + * The object must have `T get(Socket &) const`, T can be any type and it is the value * returned from this function. * * \pre isOpen() @@ -1306,7 +1519,7 @@ { assert(m_handle != Invalid); - bind(address.address(), address.length()); + bind(address.get(), address.length()); } /** @@ -1411,8 +1624,7 @@ * \param s2 the second socket * \return true if they equals */ -template -inline bool operator==(const Socket
&s1, const Socket
&s2) +inline bool operator==(const Socket &s1, const Socket &s2) { return s1.handle() == s2.handle(); } @@ -1424,8 +1636,7 @@ * \param s2 the second socket * \return true if they are different */ -template -inline bool operator!=(const Socket
&s1, const Socket
&s2) +inline bool operator!=(const Socket &s1, const Socket &s2) { return s1.handle() != s2.handle(); } @@ -1437,8 +1648,7 @@ * \param s2 the second socket * \return true if s1 < s2 */ -template -inline bool operator<(const Socket
&s1, const Socket
&s2) +inline bool operator<(const Socket &s1, const Socket &s2) { return s1.handle() < s2.handle(); } @@ -1450,8 +1660,7 @@ * \param s2 the second socket * \return true if s1 > s2 */ -template -inline bool operator>(const Socket
&s1, const Socket
&s2) +inline bool operator>(const Socket &s1, const Socket &s2) { return s1.handle() > s2.handle(); } @@ -1463,8 +1672,7 @@ * \param s2 the second socket * \return true if s1 <= s2 */ -template -inline bool operator<=(const Socket
&s1, const Socket
&s2) +inline bool operator<=(const Socket &s1, const Socket &s2) { return s1.handle() <= s2.handle(); } @@ -1476,8 +1684,7 @@ * \param s2 the second socket * \return true if s1 >= s2 */ -template -inline bool operator>=(const Socket
&s1, const Socket
&s2) +inline bool operator>=(const Socket &s1, const Socket &s2) { return s1.handle() >= s2.handle(); } @@ -1488,21 +1695,22 @@ * * This is the basic TCP protocol that implements recv, send, connect and accept as wrappers of the usual C functions. */ -template -class TcpSocket : public Socket
{ +class TcpSocket : public Socket { public: /** * Inherited constructors. */ - using Socket
::Socket; + using Socket::Socket; /** - * Create a TCP socket using the address domain. + * Construct a TCP socket. * + * \param domain the domain + * \param protocol the protocol * \throw Error on errors */ - inline TcpSocket() - : Socket
(Address().domain(), SOCK_STREAM, 0) + inline TcpSocket(int domain, int protocol) + : Socket(domain, SOCK_STREAM, protocol) { } @@ -1552,7 +1760,7 @@ */ void connect(const Address &address) { - connect(address.address(), address.length()); + connect(address.get(), address.length()); } /** @@ -1564,7 +1772,7 @@ * \throw WouldBlockError if the socket is marked non-blocking and no connection are available * \throw Error on other errors */ - TcpSocket
accept() + TcpSocket accept() { Handle handle = ::accept(this->m_handle, nullptr, 0); @@ -1584,7 +1792,7 @@ #endif } - return TcpSocket
(handle); + return TcpSocket(handle); } /** @@ -1655,21 +1863,22 @@ * * This class is the basic implementation of UDP sockets. */ -template -class UdpSocket : public Socket
{ +class UdpSocket : public Socket { public: /** * Inherited constructors. */ - using Socket
::Socket; + using Socket::Socket; /** - * Create a UDP socket using the address domain. + * Construct a TCP socket. * + * \param domain the domain + * \param protocol the protocol * \throw Error on errors */ - inline UdpSocket() - : Socket
(Address().domain(), SOCK_DGRAM, 0) + inline UdpSocket(int domain, int protocol) + : Socket(domain, SOCK_DGRAM, protocol) { } @@ -1787,7 +1996,7 @@ */ inline unsigned sendto(const void *data, unsigned length, const Address &address) { - return sendto(data, length, address.address(), address.length()); + return sendto(data, length, address.get(), address.length()); } }; @@ -1798,8 +2007,7 @@ * \ingroup net-module-tls * \warning This class is highly experimental. */ -template -class TlsSocket : public Socket
{ +class TlsSocket : public Socket { public: /** * \brief SSL connection mode. @@ -1852,14 +2060,14 @@ public: /** - * Wrap a socket around an existing one. + * Wrap a socket around an existing one, takes ownership. * * \param sock the TCP socket * \param mode the mode * \param method the method */ - inline TlsSocket(TcpSocket
&sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method()) - : Socket
(sock.handle()) + inline TlsSocket(TcpSocket sock, Mode mode = Server, const SSL_METHOD *method = TLSv1_method()) + : Socket(std::move(sock)) { #if !defined(NET_NO_SSL_AUTO_INIT) ssl::init(); @@ -1961,870 +2169,272 @@ #endif // !NET_NO_SSL /** - * \brief Predefined addresses. + * \brief IPv4 functions. */ -namespace address { +namespace ipv4 { /** - * \brief Generic address. - * \ingroup net-module-addresses + * Create an address to bind on any. * - * This address can store anything that fits into a sockaddr_storage. + * \param port the port + * \return the address */ -class Generic { -private: - sockaddr_storage m_address; - socklen_t m_length{0}; - -public: - /** - * Construct a null address. - */ - inline Generic() noexcept - { - std::memset(&m_address, 0, sizeof (sockaddr_storage)); - } - - /** - * Construct an address. - * - * \pre address is not null - * \pre length <= sizeof (sockaddr_storage) - * \param address the address to copy - * \param length the address length - */ - inline Generic(const sockaddr *address, socklen_t length) noexcept - : m_length(length) - { - assert(address); - assert(length <= sizeof (sockaddr_storage)); - - std::memset(&m_address, 0, sizeof (sockaddr_storage)); - std::memcpy(&m_address, address, length); - } - - /** - * Get the address family. - * - * \return the address family - */ - inline int domain() const noexcept - { - return m_address.ss_family; - } - - /** - * Get the underlying address. - * - * \return the address - */ - inline sockaddr *address() noexcept - { - return reinterpret_cast(&m_address); - } - - /** - * Overloaded function. - * - * \return the address - */ - inline const sockaddr *address() const noexcept - { - return reinterpret_cast(&m_address); - } - - /** - * Get the underlying address length. - * - * \return the length - */ - inline socklen_t length() const noexcept - { - return m_length; - } -}; - -/** - * Compare two generic addresses. - * - * \param a1 the first address - * \param a2 the second address - * \return true if they equal - */ -inline bool operator==(const Generic &a1, const Generic &a2) noexcept +inline Address any(std::uint16_t port) { - return a1.length() == a2.length() && std::memcmp(a1.address(), a2.address(), a1.length()) == 0; + sockaddr_in sin; + socklen_t length = sizeof (sockaddr_in); + + std::memset(&sin, 0, sizeof (sockaddr_in)); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(port); + + return Address(reinterpret_cast(&sin), length); } /** - * Compare two generic addresses. + * Create an address from a IPv4 string. * - * \param a1 the first address - * \param a2 the second address - * \return false if they equal + * \param ip the ip address + * \param port the port + * \return the address + * \throw Error if inet_pton is unavailable */ -inline bool operator!=(const Generic &a1, const Generic &a2) noexcept +inline Address pton(const std::string &ip, std::uint16_t port) { - return !(a1 == a2); +#if defined(NET_HAVE_INET_PTON) +#if !defined(NET_NO_AUTO_INIT) + init(); +#endif + + sockaddr_in sin; + socklen_t length = sizeof (sockaddr_in); + + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + + if (inet_pton(AF_INET, ip.c_str(), &sin.sin_addr) <= 0) + throw Error(); + + return Address(reinterpret_cast(&sin), length); +#else + (void)ip; + (void)port; + + throw Error(std::strerror(ENOSYS)); +#endif +} + +/** + * Get the underlying ip from the given address. + * + * \pre address.domain() == AF_INET + * \param address the IPv6 address + * \return the ip address + * \throw Error if inet_ntop is unavailable + */ +inline std::string ntop(const Address &address) +{ + assert(address.domain() == AF_INET); + +#if !defined(NET_NO_AUTO_INIT) + init(); +#endif + +#if defined(NET_HAVE_INET_NTOP) + char result[INET_ADDRSTRLEN + 1]; + + std::memset(result, 0, sizeof (result)); + + if (!inet_ntop(AF_INET, const_cast(&address.as().sin_addr), result, sizeof (result))) + throw Error(); + + return result; +#else + (void)address; + + throw Error(std::strerror(ENOSYS)); +#endif } /** - * \brief Generic IP address. - * \ingroup net-module-addresses + * Get the port from the IPv4 address. * - * You can use this address instead of Ipv4 or Ipv6 if you don't know which address to use at runtime. However, - * when creating your socket, you will need to define the correct domain. + * \pre address.domain() == AF_INET4 + * \param address the address + * \return the port + */ +inline std::uint16_t port(const Address &address) noexcept +{ + assert(address.domain() == AF_INET); + + return ntohs(address.as().sin_port); +} + +} // !ipv4 + +/** + * \brief IPv6 functions. */ -class Ip { -private: - union { - sockaddr_in6 m_sin6; - sockaddr_in m_sin; - }; - - int m_domain; - -public: - /** - * Create IP address, defaults to IPv4. - * - * \pre domain must be AF_INET or AF_INET6 - * \param domain the domain - */ - inline Ip(int domain = AF_INET) noexcept - : m_domain(domain) - { - assert(domain == AF_INET || domain == AF_INET6); - - std::memset(&m_sin, 0, sizeof (sockaddr_in)); - } - - /** - * Create an IP address on the specific ip address. - * - * \pre domain must be AF_INET or AF_INET6 - * \param ip the address or "*" for any - * \param port the port - * \param domain the domain - * \warning If NET_HAVE_INET_PTON is undefined, host can not be other than "*" - * \throw Error on failures or if inet_pton is unavailable - */ - inline Ip(const std::string &ip, std::uint16_t port, int domain) - : Ip(domain) - { - if (m_domain == AF_INET) - make(ip, port, m_sin); - else - make(ip, port, m_sin6); - } - - /** - * Create the IP address from the storage. - * - * \pre the storage domain must be AF_INET or AF_INET6 - * \param ss the the storage - * \param length the storage length - */ - inline Ip(const sockaddr *ss, socklen_t length) noexcept - : Ip(ss->sa_family) - { - assert(ss->sa_family == AF_INET || ss->sa_family == AF_INET6); - - if (ss->sa_family == AF_INET) - std::memcpy(&m_sin, ss, length); - else - std::memcpy(&m_sin6, ss, length); - } - - /** - * Get the domain. - * - * \return AF_INET or AF_INET6 - */ - inline int domain() const noexcept - { - return m_domain; - } - - /** - * Get the underlying address, may be a sockaddr_in or sockaddr_in6. - * - * \return the address - */ - inline const sockaddr *address() const noexcept - { - return m_domain == AF_INET ? reinterpret_cast(&m_sin) : reinterpret_cast(&m_sin6); - } - - /** - * Get the address length. - * - * \return the address length - */ - inline socklen_t length() const noexcept - { - return m_domain == AF_INET ? sizeof (sockaddr_in) : sizeof (sockaddr_in6); - } - - /** - * Retrieve the port. - * - * \return the port - */ - inline std::uint16_t port() const noexcept - { - return m_domain == AF_INET ? ntohs(m_sin.sin_port) : ntohs(m_sin6.sin6_port); - } - - /** - * Get the ip address. - * - * \return the ip address - * \throw Error on errors or if inet_ntop is unavailable - */ - inline std::string ip() const - { - return m_domain == AF_INET ? ip(m_sin) : ip(m_sin6); - } - - /** - * Prepare the sockaddr_in structure with the given ip. - * - * \param ip the ip address - * \param port the port - * \param sin the Ipv4 address - * \throw Error if inet_pton is unavailable - */ - static void make(const std::string &ip, std::uint16_t port, sockaddr_in &sin) - { -#if !defined(NET_NO_AUTO_INIT) - init(); -#endif - - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - - if (ip == "*") - sin.sin_addr.s_addr = INADDR_ANY; -#if defined(NET_HAVE_INET_PTON) - else if (inet_pton(AF_INET, ip.c_str(), &sin.sin_addr) <= 0) - throw Error(); -#else - else - throw Error(std::strerror(ENOSYS)); -#endif - } - - /** - * Prepare the sockaddr_in structure with the given ip. - * - * \param ip the ip address - * \param port the port - * \param sin6 the Ipv6 address - * \throw Error if inet_pton is unavailable - */ - static void make(const std::string &ip, std::uint16_t port, sockaddr_in6 &sin6) - { -#if !defined(NET_NO_AUTO_INIT) - init(); -#endif - - sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(port); - - if (ip == "*") - sin6.sin6_addr = in6addr_any; -#if defined(NET_HAVE_INET_PTON) - else if (inet_pton(AF_INET6, ip.c_str(), &sin6.sin6_addr) <= 0) - throw Error(); -#else - else - throw Error(std::strerror(ENOSYS)); -#endif - } - - /** - * Get the underlying ip from the given address. - * - * \param sin the Ipv4 address - * \return the ip address - * \throw Error if inet_ntop is unavailable - */ - static std::string ip(const sockaddr_in &sin) - { -#if !defined(NET_NO_AUTO_INIT) - init(); -#endif - -#if !defined(NET_HAVE_INET_NTOP) - (void)sin; - - throw Error(std::strerror(ENOSYS)); -#else - char result[INET_ADDRSTRLEN + 1]; - - std::memset(result, 0, sizeof (result)); - - if (!inet_ntop(AF_INET, const_cast(&sin.sin_addr), result, sizeof (result))) - throw Error(); - - return result; -#endif - } - - /** - * Get the underlying ip from the given address. - * - * \param sin6 the Ipv6 address - * \return the ip address - * \throw Error if inet_ntop is unavailable - */ - static std::string ip(const sockaddr_in6 &sin6) - { -#if !defined(NET_NO_AUTO_INIT) - init(); -#endif - -#if !defined(NET_HAVE_INET_NTOP) - (void)sin6; - - throw Error(std::strerror(ENOSYS)); -#else - char result[INET6_ADDRSTRLEN]; - - std::memset(result, 0, sizeof (result)); - - if (!inet_ntop(AF_INET6, const_cast(&sin6.sin6_addr), result, sizeof (result))) - throw Error(); - - return result; -#endif - } - - /** - * Resolve an hostname. - * - * This function wraps getaddrinfo and returns the first result. - * - * \param host the hostname - * \param service the service name (port or name) - * \param domain the domain (e.g. AF_INET) - * \param type the socket type (e.g. SOCK_STREAM) - * \return the resolved address - * \throw Error on failures - */ - static Ip resolve(const std::string &host, const std::string &service, int domain = AF_INET, int type = SOCK_STREAM) - { - assert(domain == AF_INET || domain == AF_INET6); - -#if !defined(NET_NO_AUTO_INIT) - init(); -#endif - - struct addrinfo hints, *res; - - std::memset(&hints, 0, sizeof (struct addrinfo)); - hints.ai_family = domain; - hints.ai_socktype = type; - - int e = getaddrinfo(host.c_str(), service.c_str(), &hints, &res); - - if (e != 0) - throw Error(gai_strerror(e)); - - Ip ip(res->ai_addr, res->ai_addrlen); - - freeaddrinfo(res); - - return ip; - } -}; +namespace ipv6 { + +/** + * Create an address to bind on any. + * + * \param port the port + * \return the address + */ +inline Address any(std::uint16_t port) +{ + sockaddr_in6 sin6; + socklen_t length = sizeof (sockaddr_in6); + + std::memset(&sin6, 0, sizeof (sockaddr_in6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_addr = in6addr_any; + sin6.sin6_port = htons(port); + + return Address(reinterpret_cast(&sin6), length); +} /** - * \brief Ipv4 only address. - * \ingroup net-module-addresses + * Create an address from a IPv4 string. + * + * \param ip the ip address + * \param port the port + * \return the address + * \throw Error if inet_pton is unavailable */ -class Ipv4 { -private: - sockaddr_in m_sin; - -public: - /** - * Create an Ipv4 address. - */ - inline Ipv4() noexcept - { - std::memset(&m_sin, 0, sizeof (sockaddr_in)); - } - - /** - * Create an Ipv4 address on the specific ip address. - * - * \param ip the address or "*" for any - * \param port the port - * \warning If NET_HAVE_INET_PTON is undefined, host can not be other than "*" - * \throw Error on failures or if inet_pton is unavailable - */ - inline Ipv4(const std::string &ip, std::uint16_t port) - : Ipv4() - { - Ip::make(ip, port, m_sin); - } - - /** - * Create the IP address from the storage. - * - * \pre the storage domain must be AF_INET - * \param ss the the storage - * \param length the storage length - */ - inline Ipv4(const sockaddr *ss, socklen_t length) noexcept - { - assert(ss->sa_family == AF_INET); - - std::memcpy(&m_sin, ss, length); - } - - /** - * Get the domain. - * - * \return AF_INET - */ - inline int domain() const noexcept - { - return AF_INET; - } - - /** - * Get the underlying address. - * - * \return the address - */ - inline const sockaddr *address() const noexcept - { - return reinterpret_cast(&m_sin); - } - - /** - * Get the address length. - * - * \return the size of sockaddr_in - */ - inline socklen_t length() const noexcept - { - return sizeof (sockaddr_in); - } - - /** - * Get the port. - * - * \return the port - */ - inline std::uint16_t port() const noexcept - { - return ntohs(m_sin.sin_port); - } - - /** - * Get the ip address. - * - * \return the ip address - * \throw Error on errors or if inet_ntop is unavailable - */ - inline std::string ip() const - { - return Ip::ip(m_sin); - } - - /** - * Same as Ip::resolve with AF_INET as domain. - * - * \param host the hostname - * \param service the service name (port or name) - * \param type the socket type (e.g. SOCK_STREAM) - * \return the resolved address - * \throw Error on failures - */ - static Ipv4 resolve(const std::string &host, const std::string &service, int type = SOCK_STREAM) - { - Ip result = Ip::resolve(host, service, AF_INET, type); - - return Ipv4(result.address(), result.length()); - } -}; +inline Address pton(const std::string &ip, std::uint16_t port) +{ +#if defined(NET_HAVE_INET_PTON) +#if !defined(NET_NO_AUTO_INIT) + init(); +#endif + + sockaddr_in6 sin6; + socklen_t length = sizeof (sockaddr_in6); + + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(port); + + + if (inet_pton(AF_INET6, ip.c_str(), &sin6.sin6_addr) <= 0) + throw Error(); + + return Address(reinterpret_cast(&sin6), length); +#else + (void)ip; + (void)port; + + throw Error(std::strerror(ENOSYS)); +#endif +} /** - * \brief Ipv4 only address. - * \ingroup net-module-addresses + * Get the underlying ip from the given address. + * + * \pre address.domain() == AF_INET6 + * \param address the IPv6 address + * \return the ip address + * \throw Error if inet_ntop is unavailable */ -class Ipv6 { -private: - sockaddr_in6 m_sin6; - -public: - /** - * Create an Ipv6 address. - */ - inline Ipv6() noexcept - { - std::memset(&m_sin6, 0, sizeof (sockaddr_in6)); - } - - /** - * Create an Ipv6 address on the specific ip address. - * - * \param ip the address or "*" for any - * \param port the port - * \warning If NET_HAVE_INET_PTON is undefined, host can not be other than "*" - * \throw Error on failures or if inet_pton is unavailable - */ - inline Ipv6(const std::string &ip, std::uint16_t port) - : Ipv6() - { - Ip::make(ip, port, m_sin6); - } - - /** - * Create the IP address from the storage. - * - * \pre the storage domain must be AF_INET6 - * \param ss the the storage - * \param length the storage length - */ - inline Ipv6(const sockaddr *ss, socklen_t length) noexcept - { - assert(ss->sa_family == AF_INET6); - - std::memcpy(&m_sin6, ss, length); - } - - /** - * Get the domain. - * - * \return AF_INET6 - */ - inline int domain() const noexcept - { - return AF_INET6; - } - - /** - * Get the underlying address. - * - * \return the address - */ - inline const sockaddr *address() const noexcept - { - return reinterpret_cast(&m_sin6); - } - - /** - * Get the address length. - * - * \return the size of sockaddr_in - */ - inline socklen_t length() const noexcept - { - return sizeof (sockaddr_in6); - } - - /** - * Get the port. - * - * \return the port - */ - inline std::uint16_t port() const noexcept - { - return ntohs(m_sin6.sin6_port); - } - - /** - * Get the ip address. - * - * \return the ip address - * \throw Error on errors or if inet_ntop is unavailable - */ - inline std::string ip() const - { - return Ip::ip(m_sin6); - } - - /** - * Same as Ip::resolve with AF_INET6 as domain. - * - * \param host the hostname - * \param service the service name (port or name) - * \param type the socket type (e.g. SOCK_STREAM) - * \return the resolved address - * \throw Error on failures - */ - static Ipv6 resolve(const std::string &host, const std::string &service, int type = SOCK_STREAM) - { - Ip result = Ip::resolve(host, service, AF_INET6, type); - - return Ipv6(result.address(), result.length()); - } -}; +inline std::string ntop(const Address &address) +{ + assert(address.domain() == AF_INET6); + +#if defined(NET_HAVE_INET_NTOP) +#if !defined(NET_NO_AUTO_INIT) + init(); +#endif + + char ret[INET6_ADDRSTRLEN]; + + std::memset(ret, 0, sizeof (ret)); + + if (!inet_ntop(AF_INET6, const_cast(&address.as().sin6_addr), ret, sizeof (ret))); + throw Error(); + + return ret; +#else + (void)address; + + throw Error(std::strerror(ENOSYS)); +#endif +} + +/** + * Get the port from the IPv6 address. + * + * \pre address.domain() == AF_INET6 + * \param address the address + * \return the port + */ +inline std::uint16_t port(const Address &address) noexcept +{ + assert(address.domain() == AF_INET6); + + return ntohs(address.as().sin6_port); +} + +} // !ipv6 #if !defined(_WIN32) /** - * \brief unix family sockets - * \ingroup net-module-addresses - * - * Create an address to a specific path. Only available on Unix. + * \brief Unix domain functions. */ -class Local { -private: - sockaddr_un m_sun; - std::string m_path; - -public: - /** - * Get the domain AF_LOCAL. - * - * \return AF_LOCAL - */ - inline int domain() const noexcept - { - return AF_LOCAL; - } - - /** - * Default constructor. - */ - inline Local() noexcept - { - std::memset(&m_sun, 0, sizeof (sockaddr_un)); - } - - /** - * Construct an address to a path. - * - * \param path the path - * \param rm remove the file before (default: false) - */ - Local(std::string path, bool rm = false) noexcept - : m_path(std::move(path)) - { - // Silently remove the file even if it fails. - if (rm) - ::remove(m_path.c_str()); - - // Copy the path. - std::memset(m_sun.sun_path, 0, sizeof (m_sun.sun_path)); - std::strncpy(m_sun.sun_path, m_path.c_str(), sizeof (m_sun.sun_path) - 1); - - // Set the parameters. - m_sun.sun_family = AF_LOCAL; - } - - /** - * Construct an unix address from a storage address. - * - * \pre storage's domain must be AF_LOCAL - * \param ss the storage - * \param length the length - */ - Local(const sockaddr *ss, socklen_t length) noexcept - { - assert(ss->sa_family == AF_LOCAL); - - std::memcpy(&m_sun, ss, length); - m_path = reinterpret_cast(m_sun).sun_path; - } - - /** - * Get the sockaddr_un. - * - * \return the address - */ - inline const sockaddr *address() const noexcept - { - return reinterpret_cast(&m_sun); - } - - /** - * Get the address length. - * - * \return the length - */ - inline socklen_t length() const noexcept - { -#if defined(NET_HAVE_SUN_LEN) - return SUN_LEN(&m_sun); -#else - return sizeof (m_sun); -#endif - } -}; - -#endif // !_WIN32 +namespace local { /** - * \brief Address iterator. - * \ingroup net-module-addresses - * \see resolve - * - * This iterator can be used to try to connect to an host. - * - * When you use resolve with unspecified domain or socket type, the function may retrieve several different addresses that you can - * iterate over to try to connect to. + * Construct an address to a path. * - * Example: - * - * ````cpp - * SocketTcpIp sc; - * Iterator end, it = resolve("hostname.test", "80"); - * - * while (!connected_condition && it != end) - * sc.connect(it->address(), it->length()); - * ```` - * - * When an iterator equals to a default constructed iterator, it is considered not dereferenceable. + * \pre !path.empty() + * \param path the path + * \param rm remove the file before (default: false) */ -class Iterator : public std::iterator { -private: - std::vector m_addresses; - std::size_t m_index{0}; - -public: - /** - * Construct a null iterator. - * - * The default constructed iterator is not dereferenceable. - */ - inline Iterator() noexcept = default; - - /** - * Construct an address iterator with a set of addresses. - * - * \pre index < m_addresses.size() - * \param addresses the addresses - * \param index the first index - */ - inline Iterator(std::vector addresses, std::size_t index = 0) noexcept - : m_addresses(std::move(addresses)) - , m_index(index) - { - assert(index < m_addresses.size()); - } - - /** - * Get the generic address. - * - * \pre this is dereferenceable - * \return the generic address - */ - inline const Generic &operator*() const noexcept - { - assert(m_index <= m_addresses.size()); - - return m_addresses[m_index]; - } - - /** - * Overloaded function. - * - * \pre this is dereferenceable - * \return the generic address - */ - inline Generic &operator*() noexcept - { - assert(m_index <= m_addresses.size()); - - return m_addresses[m_index]; - } - - /** - * Get the generic address. - * - * \pre this is dereferenceable - * \return the generic address - */ - inline const Generic *operator->() const noexcept - { - assert(m_index <= m_addresses.size()); - - return &m_addresses[m_index]; - } - - /** - * Overloaded function. - * - * \pre this is dereferenceable - * \return the generic address - */ - inline Generic *operator->() noexcept - { - assert(m_index <= m_addresses.size()); - - return &m_addresses[m_index]; - } - - /** - * Pre-increment the iterator. - * - * \return this - */ - inline Iterator &operator++(int) noexcept - { - if (m_index + 1 >= m_addresses.size()) { - m_addresses.clear(); - m_index = 0; - } else - m_index ++; - - return *this; - } - - /** - * Post-increment the iterator. - * - * \return copy of this - */ - inline Iterator operator++() noexcept - { - Iterator save = *this; - - if (m_index + 1 >= m_addresses.size()) { - m_addresses.clear(); - m_index = 0; - } else - m_index ++; - - return save; - } - - friend bool operator==(const Iterator &, const Iterator &) noexcept; - friend bool operator!=(const Iterator &, const Iterator &) noexcept; -}; - -/** - * Compare two address iterators. - * - * \param i1 the first iterator - * \param i2 the second iterator - * \return true if they equal - */ -inline bool operator==(const Iterator &i1, const Iterator &i2) noexcept +inline Address create(const std::string &path, bool rm = false) noexcept { - return i1.m_addresses == i2.m_addresses && i1.m_index == i2.m_index; + assert(!path.empty()); + + // Silently remove the file even if it fails. + if (rm) + remove(path.c_str()); + + sockaddr_un sun; + socklen_t length; + + std::memset(sun.sun_path, 0, sizeof (sun.sun_path)); + std::strncpy(sun.sun_path, path.c_str(), sizeof (sun.sun_path) - 1); + + sun.sun_family = AF_LOCAL; + +#if defined(NET_HAVE_SUN_LEN) + length = SUN_LEN(&sun); +#else + length = sizeof (sun); +#endif + + return Address(reinterpret_cast(&sun), length); } /** - * Compare two address iterators. + * Get the path from the address. * - * \param i1 the first iterator - * \param i2 the second iterator - * \return false if they equal + * \pre address.domain() == AF_LOCAL + * \param address the local address + * \return the path to the socket file */ -inline bool operator!=(const Iterator &i1, const Iterator &i2) noexcept +inline std::string path(const Address &address) { - return !(i1 == i2); + assert(address.domain() == AF_LOCAL); + + return reinterpret_cast(address.get())->sun_path; } -} // !address +} // !local + +#endif // !_WIN32 /** * \brief Predefined options. @@ -2859,8 +2469,7 @@ * \param sc the socket * \throw Error on errors */ - template - void set(Socket
&sc) const + void set(Socket &sc) const { #if defined(O_NONBLOCK) && !defined(_WIN32) int flags; @@ -2890,8 +2499,7 @@ * \return the value * \throw Error on errors */ - template - bool get(Socket
&sc) const + bool get(Socket &sc) const { #if defined(O_NONBLOCK) && !defined(_WIN32) int flags = fcntl(sc.handle(), F_GETFL, 0); @@ -2933,8 +2541,7 @@ * \param sc the socket * \throw Error on errors */ - template - inline void set(Socket
&sc) const + inline void set(Socket &sc) const { sc.set(SOL_SOCKET, SO_RCVBUF, m_value); } @@ -2946,10 +2553,9 @@ * \return the value * \throw Error on errors */ - template - inline int get(Socket
&sc) const + inline int get(Socket &sc) const { - return sc.template get(SOL_SOCKET, SO_RCVBUF); + return sc.get(SOL_SOCKET, SO_RCVBUF); } }; @@ -2980,8 +2586,7 @@ * \param sc the socket * \throw Error on errors */ - template - inline void set(Socket
&sc) const + inline void set(Socket &sc) const { sc.set(SOL_SOCKET, SO_REUSEADDR, m_value ? 1 : 0); } @@ -2993,10 +2598,9 @@ * \return the value * \throw Error on errors */ - template - inline bool get(Socket
&sc) const + inline bool get(Socket &sc) const { - return sc.template get(SOL_SOCKET, SO_REUSEADDR) != 0; + return sc.get(SOL_SOCKET, SO_REUSEADDR) != 0; } }; @@ -3025,8 +2629,7 @@ * \param sc the socket * \throw Error on errors */ - template - inline void set(Socket
&sc) const + inline void set(Socket &sc) const { sc.set(SOL_SOCKET, SO_SNDBUF, m_value); } @@ -3038,10 +2641,9 @@ * \return the value * \throw Error on errors */ - template - inline int get(Socket
&sc) const + inline int get(Socket &sc) const { - return sc.template get(SOL_SOCKET, SO_SNDBUF); + return sc.get(SOL_SOCKET, SO_SNDBUF); } }; @@ -3072,8 +2674,7 @@ * \param sc the socket * \throw Error on errors */ - template - inline void set(Socket
&sc) const + inline void set(Socket &sc) const { sc.set(IPPROTO_TCP, TCP_NODELAY, m_value ? 1 : 0); } @@ -3085,10 +2686,9 @@ * \return the value * \throw Error on errors */ - template - inline bool get(Socket
&sc) const + inline bool get(Socket &sc) const { - return sc.template get(IPPROTO_TCP, TCP_NODELAY) != 0; + return sc.get(IPPROTO_TCP, TCP_NODELAY) != 0; } }; @@ -3122,8 +2722,7 @@ * \param sc the socket * \throw Error on errors */ - template - inline void set(Socket
&sc) const + inline void set(Socket &sc) const { sc.set(IPPROTO_IPV6, IPV6_V6ONLY, m_value ? 1 : 0); } @@ -3135,10 +2734,9 @@ * \return the value * \throw Error on errors */ - template - inline bool get(Socket
&sc) const + inline bool get(Socket &sc) const { - return sc.template get(IPPROTO_IPV6, IPV6_V6ONLY) != 0; + return sc.get(IPPROTO_IPV6, IPV6_V6ONLY) != 0; } }; @@ -3968,80 +3566,6 @@ }; /** - * \ingroup net-module-tcp - * \brief Helper to create TCP/Ipv4 or TCP/Ipv6 sockets. - */ -using TcpSocketIp = TcpSocket; - -/** - * \ingroup net-module-tcp - * \brief Helper to create TCP/Ipv4 sockets. - */ -using TcpSocketIpv4 = TcpSocket; - -/** - * \ingroup net-module-tcp - * \brief Helper to create TCP/Ipv6 sockets. - */ -using TcpSocketIpv6 = TcpSocket; - -/** - * \ingroup net-module-udp - * \brief Helper to create UDP/Ipv4 or UDP/Ipv6 sockets. - */ -using UdpSocketIp = UdpSocket; - -/** - * \ingroup net-module-udp - * \brief Helper to create UDP/Ipv4 sockets. - */ -using UdpSocketIpv4 = UdpSocket; - -/** - * \ingroup net-module-udp - * \brief Helper to create UDP/Ipv6 sockets. - */ -using UdpSocketIpv6 = UdpSocket; - -#if !defined(_WIN32) - -/** - * \ingroup net-module-tcp - * \brief Helper to create TCP/Local sockets. - */ -using TcpSocketLocal = TcpSocket; - -/** - * \ingroup net-module-udp - * \brief Helper to create UDP/Local sockets. - */ -using UdpSocketLocal = TcpSocket; - -#endif - -#if !defined(NET_NO_SSL) - -/** - * \ingroup net-module-tls - * \brief Helper to create TLS/Ipv4 or TLS/Ipv6 sockets. - */ -using TlsSocketIp = TlsSocket; - -/** - * \ingroup net-module-tls - * \brief Helper to create TLS/Ipv4 sockets. - */ -using TlsSocketIpv4 = TlsSocket; - -/** - * \ingroup net-module-tls - * \brief Helper to create TLS/Ipv6 sockets. - */ -using TlsSocketIpv6 = TlsSocket; - -#endif - -/** * \ingroup net-module-resolv * * Resolve an hostname immediately. @@ -4053,7 +3577,7 @@ * \return the address iterator * \throw Error on failures */ -inline address::Iterator resolve(const std::string &host, const std::string &service, int domain = AF_UNSPEC, int type = 0) +inline AddressIterator resolve(const std::string &host, const std::string &service, int domain = AF_UNSPEC, int type = 0) { #if !defined(NET_NO_AUTO_INIT) init(); @@ -4070,29 +3594,12 @@ if (e != 0) throw Error(gai_strerror(e)); - std::vector addresses; + std::vector
addresses; for (p = res; p != nullptr; p = p->ai_next) - addresses.push_back(address::Generic(p->ai_addr, p->ai_addrlen)); - - return address::Iterator(addresses, 0); -} - -/** - * \ingroup net-module-resolv - * - * Overloaded function. - * - * \param sc the parent socket - * \param host the hostname - * \param service the service name - * \return the address iterator - * \throw Error on failures - */ -template -address::Iterator resolve(const Socket
&sc, const std::string &host, const std::string &service) -{ - return resolve(host, service, Address().domain(), sc.type()); + addresses.push_back(Address(p->ai_addr, p->ai_addrlen)); + + return AddressIterator(addresses, 0); } /** @@ -4108,10 +3615,10 @@ * \throw Error on failures * \note do not use AF_UNSPEC and 0 as type for this function */ -inline address::Generic resolveOne(const std::string &host, const std::string &service, int domain, int type) +inline Address resolveOne(const std::string &host, const std::string &service, int domain, int type) { - address::Iterator end; - address::Iterator it = resolve(host, service, domain, type); + AddressIterator it = resolve(host, service, domain, type); + AddressIterator end; if (it == end) throw Error("no address available"); @@ -4119,23 +3626,6 @@ return *it; } -/** - * \ingroup net-module-resolv - * - * Overloaded function - * - * \param sc the parent socket - * \param host the hostname - * \param service the service name - * \return the first generic address available - * \throw Error on failures - */ -template -address::Generic resolveOne(const Socket
&sc, const std::string &host, const std::string &service) -{ - return resolveOne(host, service, Address().domain(), sc.type()); -} - } // !net #endif // !NET_HPP diff -r c79a501782b0 -r ad302d1b7335 modules/net/test/main.cpp --- a/modules/net/test/main.cpp Wed Jun 29 19:18:39 2016 +0200 +++ b/modules/net/test/main.cpp Thu Jun 30 12:35:42 2016 +0200 @@ -27,7 +27,6 @@ #include using namespace net; -using namespace net::address; using namespace net::option; using namespace std::literals::chrono_literals; @@ -39,7 +38,7 @@ TEST(Options, reuse) { - TcpSocketIp s; + TcpSocket s(AF_INET, 0); try { s.set(option::SockReuseAddress(true)); @@ -54,7 +53,7 @@ TEST(Options, nodelay) { - TcpSocketIp s; + TcpSocket s(AF_INET, 0); try { s.set(option::TcpNoDelay(true)); @@ -69,7 +68,7 @@ TEST(Options, v6only) { - TcpSocketIpv6 s; + TcpSocket s(AF_INET6, 0); try { s.set(option::Ipv6Only(true)); @@ -89,8 +88,8 @@ class TcpServerTest : public testing::Test { protected: - TcpSocketIpv4 m_server; - TcpSocketIpv4 m_client; + TcpSocket m_server{AF_INET, 0}; + TcpSocket m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -114,9 +113,9 @@ { m_tserver = std::thread([this] () { try { - TcpSocketIpv4 sc; + TcpSocket sc(AF_INET, 0); - m_server.bind(Ipv4("*", 16000)); + m_server.bind(net::ipv4::any(16000)); m_server.listen(); m_server.accept(); m_server.close(); @@ -129,7 +128,7 @@ m_tclient = std::thread([this] () { try { - m_client.connect(Ipv4("127.0.0.1", 16000)); + m_client.connect(net::ipv4::pton("127.0.0.1", 16000)); m_client.close(); } catch (const std::exception &ex) { FAIL() << ex.what(); @@ -140,10 +139,10 @@ TEST_F(TcpServerTest, io) { m_tserver = std::thread([this] () { - m_server.bind(Ipv4("*", 16000)); + m_server.bind(net::ipv4::any(16000)); m_server.listen(); - TcpSocketIpv4 client = m_server.accept(); + TcpSocket client = m_server.accept(); std::string msg; @@ -160,7 +159,7 @@ m_tclient = std::thread([this] () { std::string msg = "hello world"; - m_client.connect(Ipv4("127.0.0.1", 16000)); + m_client.connect(net::ipv4::pton("127.0.0.1", 16000)); m_client.send(msg.c_str(), msg.length()); msg.resize(512); @@ -177,8 +176,8 @@ class UdpServerTest : public testing::Test { protected: - UdpSocketIpv4 m_server; - UdpSocketIpv4 m_client; + UdpSocket m_server{AF_INET, 0}; + UdpSocket m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -202,8 +201,8 @@ { m_tserver = std::thread([this] () { try { - Ipv4 client; - Ipv4 info("*", 16000); + Address client; + Address info = net::ipv4::any(16000); m_server.bind(info); @@ -225,7 +224,7 @@ m_tclient = std::thread([this] () { try { - Ipv4 info("127.0.0.1", 16000); + Address info = net::ipv4::pton("127.0.0.1", 16000); std::string msg = "hello world"; m_client.sendto(msg.c_str(), msg.length(), info); @@ -480,8 +479,8 @@ class ListenerTest : public testing::Test { protected: Listener m_listener; - TcpSocketIpv4 m_masterTcp; - TcpSocketIpv4 m_clientTcp; + TcpSocket m_masterTcp{AF_INET, 0}; + TcpSocket m_clientTcp{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -490,7 +489,7 @@ ListenerTest() { m_masterTcp.set(SockReuseAddress()); - m_masterTcp.bind(Ipv4("*", 16000)); + m_masterTcp.bind(net::ipv4::any(16000)); m_masterTcp.listen(); } @@ -521,7 +520,7 @@ std::this_thread::sleep_for(100ms); m_tclient = std::thread([this] () { - m_clientTcp.connect(Ipv4("127.0.0.1", 16000)); + m_clientTcp.connect(net::ipv4::pton("127.0.0.1", 16000)); }); } @@ -532,7 +531,7 @@ m_listener.set(m_masterTcp.handle(), Condition::Readable); m_listener.wait(); - TcpSocketIpv4 sc = m_masterTcp.accept(); + TcpSocket sc = m_masterTcp.accept(); std::string msg; @@ -550,7 +549,7 @@ m_tclient = std::thread([this] () { std::string msg = "hello"; - m_clientTcp.connect(Ipv4("127.0.0.1", 16000)); + m_clientTcp.connect(net::ipv4::pton("127.0.0.1", 16000)); m_clientTcp.send(msg.c_str(), msg.length()); }); } @@ -562,8 +561,8 @@ class NonBlockingConnectTest : public testing::Test { protected: - TcpSocketIpv4 m_server; - TcpSocketIpv4 m_client; + TcpSocket m_server{AF_INET, 0}; + TcpSocket m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -590,8 +589,8 @@ class TcpAcceptTest : public testing::Test { protected: - TcpSocketIpv4 m_server; - TcpSocketIpv4 m_client; + TcpSocket m_server{AF_INET, 0}; + TcpSocket m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -600,7 +599,7 @@ TcpAcceptTest() { m_server.set(SockReuseAddress()); - m_server.bind(Ipv4("*", 16000)); + m_server.bind(net::ipv4::any(16000)); m_server.listen(); } @@ -620,8 +619,8 @@ class TcpRecvTest : public testing::Test { protected: - TcpSocketIpv4 m_server; - TcpSocketIpv4 m_client; + TcpSocket m_server{AF_INET, 0}; + TcpSocket m_client{AF_INET, 0}; std::thread m_tserver; std::thread m_tclient; @@ -630,7 +629,7 @@ TcpRecvTest() { m_server.set(SockReuseAddress()); - m_server.bind(Ipv4("*", 16000)); + m_server.bind(net::ipv4::any(16000)); m_server.listen(); } @@ -646,7 +645,7 @@ TEST_F(TcpRecvTest, blockingSuccess) { m_tserver = std::thread([this] () { - TcpSocketIpv4 client = m_server.accept(); + TcpSocket client = m_server.accept(); std::string msg; msg.resize(512); @@ -660,7 +659,7 @@ m_tclient = std::thread([this] () { std::string msg = "hello"; - m_client.connect(Ipv4("127.0.0.1", 16000)); + m_client.connect(net::ipv4::pton("127.0.0.1", 16000)); m_client.send(msg.c_str(), msg.length()); m_client.close(); });