diff options
| author | Richard Qin <richard.qin.x@gmail.com> | 2026-04-11 02:20:31 +0800 |
|---|---|---|
| committer | Richard Qin <richard.qin.x@gmail.com> | 2026-04-11 02:20:31 +0800 |
| commit | 98e88c01eb0e6404d1c5f49a22165d0861e6b924 (patch) | |
| tree | d016d445fe476f747eea9030896214adeaacf51f /include/ricochet/net/sys/address.hh | |
| parent | 44ad3c8b36540c6b0b3144a21ac40310e163bb19 (diff) | |
| download | rwebbrowser-98e88c01eb0e6404d1c5f49a22165d0861e6b924.tar.gz rwebbrowser-98e88c01eb0e6404d1c5f49a22165d0861e6b924.tar.xz | |
feat: implement basic HTTP client with socket and address networking utilities
Diffstat (limited to 'include/ricochet/net/sys/address.hh')
| -rw-r--r-- | include/ricochet/net/sys/address.hh | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/include/ricochet/net/sys/address.hh b/include/ricochet/net/sys/address.hh new file mode 100644 index 0000000..39c9553 --- /dev/null +++ b/include/ricochet/net/sys/address.hh @@ -0,0 +1,88 @@ +/** + * --------------------------------------------------------------------------- + * @notice This file was adapted from the Minnow networking framework, + * originally developed for Stanford University's CS144 course. + * It has been incorporated into the Ricochet project as foundational + * system utility code. + * --------------------------------------------------------------------------- + */ + +#pragma once + +#include <cstddef> +#include <cstdint> +#include <netdb.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. + // NOLINTBEGIN (*-explicit-*) + operator sockaddr*(); + operator const sockaddr*() const; + // NOLINTEND (*-explicit-*) + }; + +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. + explicit Address( const std::string& ip, std::uint16_t port = 0 ); + + //! Construct from a [sockaddr *](@ref man7::socket). + Address( const sockaddr* addr, std::size_t size ); + + //! Default constructor + Address() : Address( nullptr, 0 ) {} + + //! 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( 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. + const sockaddr* raw() const { return static_cast<const sockaddr*>( address_ ); } + //! Safely convert to underlying sockaddr type + template<typename sockaddr_type> + const sockaddr_type* as() const; + + //!@} +}; |
