86 lines
2.8 KiB
C++
86 lines
2.8 KiB
C++
#ifndef SPONGE_LIBSPONGE_ADDRESS_HH
|
|
#define SPONGE_LIBSPONGE_ADDRESS_HH
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <netdb.h>
|
|
#include <netinet/in.h>
|
|
#include <string>
|
|
#include <sys/socket.h>
|
|
#include <utility>
|
|
|
|
//! 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<std::string, uint16_t> 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
|