#ifndef SPONGE_LIBSPONGE_ADDRESS_HH #define SPONGE_LIBSPONGE_ADDRESS_HH #include #include #include #include #include #include #include //! Wrapper around [IPv4 addresses](@ref man7::ip) and DNS operations. class Address { public: //! \brief Wrapper around [sockaddr_storage](@ref man7::socket). //! \details A `sockaddr_storage` is enough space to store any socket address (IPv4 or IPv6). class Raw { public: sockaddr_storage storage{}; //!< The wrapped struct itself. operator sockaddr *(); operator const sockaddr *() const; }; private: socklen_t _size; //!< Size of the wrapped address. Raw _address{}; //!< A wrapped [sockaddr_storage](@ref man7::socket) containing the address. //! Constructor from ip/host, service/port, and hints to the resolver. Address(const std::string &node, const std::string &service, const addrinfo &hints); public: //! Construct by resolving a hostname and servicename. Address(const std::string &hostname, const std::string &service); //! Construct from dotted-quad string ("18.243.0.1") and numeric port. Address(const std::string &ip, const std::uint16_t port = 0); //! Construct from a [sockaddr *](@ref man7::socket). Address(const sockaddr *addr, const std::size_t size); //! Equality comparison. bool operator==(const Address &other) const; bool operator!=(const Address &other) const { return not operator==(other); } //! \name Conversions //!@{ //! Dotted-quad IP address string ("18.243.0.1") and numeric port. std::pair ip_port() const; //! Dotted-quad IP address string ("18.243.0.1"). std::string ip() const { return ip_port().first; } //! Numeric port (host byte order). uint16_t port() const { return ip_port().second; } //! Numeric IP address as an integer (i.e., in [host byte order](\ref man3::byteorder)). uint32_t ipv4_numeric() const; //! Create an Address from a 32-bit raw numeric IP address static Address from_ipv4_numeric(const uint32_t ip_address); //! Human-readable string, e.g., "8.8.8.8:53". std::string to_string() const; //!@} //! \name Low-level operations //!@{ //! Size of the underlying address storage. socklen_t size() const { return _size; } //! Const pointer to the underlying socket address storage. operator const sockaddr *() const { return _address; } //!@} }; //! \class Address //! For example, you can do DNS lookups: //! //! \include address_example_1.cc //! //! or you can specify an IP address and port number: //! //! \include address_example_2.cc //! //! Once you have an address, you can convert it to other useful representations, e.g., //! //! \include address_example_3.cc #endif // SPONGE_LIBSPONGE_ADDRESS_HH