2020-05-04 21:17:16 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include "sock_addr.hpp"
|
2020-05-04 21:36:08 +00:00
|
|
|
|
2020-05-06 20:38:44 +00:00
|
|
|
#include <optional>
|
2020-05-04 21:17:16 +00:00
|
|
|
#include <string_view>
|
|
|
|
#include <string>
|
|
|
|
|
2021-03-09 22:24:35 +00:00
|
|
|
#include "net_int.hpp"
|
2020-09-24 00:28:38 +00:00
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
/// A struct that can represent either an IPv4 or IPv6 address. It is meant for representation
|
|
|
|
/// purposes only (e.g. serialization/deserialization). In addition, it also optionally stores
|
|
|
|
/// a port.
|
|
|
|
///
|
|
|
|
/// As a convenience, it can produce a SockAddr for dealing with network libraries which depend
|
|
|
|
/// sockaddr structs. However, it does not keep this as a member variable and isn't responsible
|
|
|
|
/// for its lifetime/memory/etc.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// TODO: IPv6 is not currently supported.
|
2020-05-04 21:17:16 +00:00
|
|
|
struct IpAddress
|
|
|
|
{
|
2020-05-06 20:38:44 +00:00
|
|
|
/// Empty constructor.
|
|
|
|
IpAddress() = default;
|
2020-05-21 14:22:34 +00:00
|
|
|
/// move construtor
|
|
|
|
IpAddress(IpAddress&&) = default;
|
|
|
|
/// copy construct
|
|
|
|
IpAddress(const IpAddress&);
|
2020-05-06 20:38:44 +00:00
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
/// Constructor. Takes a string which can be an IPv4 or IPv6 address optionally followed by
|
|
|
|
/// a colon and a port.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// Examples:
|
|
|
|
///
|
|
|
|
/// 127.0.0.1
|
|
|
|
/// 1.2.3.4:53
|
|
|
|
///
|
|
|
|
/// Note that an IPv6 + port representation must be done in an unambiguous way, e.g. wrap the
|
|
|
|
/// IP portion of the string in brackets: [IPv6Addr]:port
|
|
|
|
///
|
|
|
|
/// @param str is a string representing an IP address and optionally a port
|
|
|
|
/// @throws std::invalid_argument if str cannot be parsed
|
2020-05-04 21:17:16 +00:00
|
|
|
IpAddress(std::string_view str);
|
|
|
|
|
|
|
|
/// Constructor. Takes an IP address (as above) and a port. The string may not contain a port.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// @param str is a string representing an IP address and optionally a port
|
|
|
|
/// @throws std::invalid_argument if str cannot be parsed
|
|
|
|
IpAddress(std::string_view str, std::optional<uint16_t> port);
|
2020-05-04 21:17:16 +00:00
|
|
|
|
2020-05-06 20:38:44 +00:00
|
|
|
/// Construct from a SockAddr.
|
|
|
|
///
|
|
|
|
/// @param addr is an SockAddr to initialize from.
|
|
|
|
IpAddress(const SockAddr& addr);
|
|
|
|
|
2020-05-11 15:11:44 +00:00
|
|
|
IpAddress&
|
2020-05-06 20:38:44 +00:00
|
|
|
operator=(const sockaddr& other);
|
|
|
|
|
2020-05-21 14:22:34 +00:00
|
|
|
/// move assignment
|
|
|
|
IpAddress&
|
|
|
|
operator=(IpAddress&& other);
|
|
|
|
|
|
|
|
/// copy assignment
|
|
|
|
IpAddress&
|
|
|
|
operator=(const IpAddress& other);
|
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
/// Return the port. Returns -1 if no port has been provided.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// @return the port, if present
|
|
|
|
std::optional<uint16_t>
|
2020-05-04 21:17:16 +00:00
|
|
|
getPort() const;
|
|
|
|
|
2020-07-30 14:36:36 +00:00
|
|
|
/// Return true if we have a port set otherwise return false
|
|
|
|
bool
|
|
|
|
hasPort() const;
|
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
/// Set the port.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// @param port
|
2020-05-04 21:17:16 +00:00
|
|
|
void
|
2020-05-04 21:36:08 +00:00
|
|
|
setPort(std::optional<uint16_t> port);
|
2020-05-04 21:17:16 +00:00
|
|
|
|
2020-05-06 20:38:44 +00:00
|
|
|
/// Set the IP address. Follows the same logic as the constructor with the same signature, but
|
|
|
|
/// doesn't overwrite the port if the port isn't present in the string.
|
|
|
|
void
|
|
|
|
setAddress(std::string_view str);
|
|
|
|
void
|
|
|
|
setAddress(std::string_view str, std::optional<uint16_t> port);
|
|
|
|
|
2020-05-04 21:36:08 +00:00
|
|
|
/// Returns true if this is an IPv4 address (or an IPv6 address representing an IPv4 address)
|
|
|
|
///
|
2020-05-04 21:17:16 +00:00
|
|
|
/// TODO: could return an int (e.g. 4 or 6) or an enum
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// @return true if this is an IPv4 address, false otherwise
|
2020-05-04 21:17:16 +00:00
|
|
|
bool
|
|
|
|
isIPv4();
|
|
|
|
|
2020-05-06 20:38:44 +00:00
|
|
|
/// Returns true if this represents a valid IpAddress, false otherwise.
|
|
|
|
///
|
|
|
|
/// @return whether or not this IpAddress is empty
|
|
|
|
bool
|
|
|
|
isEmpty() const;
|
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
/// Creates an instance of SockAddr representing this IpAddress.
|
2020-05-04 21:36:08 +00:00
|
|
|
///
|
|
|
|
/// @return an instance of a SockAddr created from this IpAddress
|
2020-05-04 21:17:16 +00:00
|
|
|
SockAddr
|
|
|
|
createSockAddr() const;
|
|
|
|
|
2020-05-06 20:38:44 +00:00
|
|
|
/// Returns true if this IpAddress is a bogon, false otherwise
|
|
|
|
///
|
|
|
|
/// @return whether or not this IpAddress is a bogon
|
|
|
|
bool
|
|
|
|
isBogon() const;
|
|
|
|
|
|
|
|
/// Returns a string representing this IpAddress
|
|
|
|
///
|
|
|
|
/// @return string representation of this IpAddress
|
|
|
|
std::string
|
|
|
|
toString() const;
|
|
|
|
|
2020-07-30 14:36:36 +00:00
|
|
|
std::string
|
2020-08-21 19:09:13 +00:00
|
|
|
toHost() const;
|
2020-07-30 14:36:36 +00:00
|
|
|
|
2020-09-24 00:28:38 +00:00
|
|
|
huint32_t
|
|
|
|
toIP() const;
|
|
|
|
|
2021-02-16 15:59:18 +00:00
|
|
|
huint128_t
|
|
|
|
toIP6() const;
|
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
// TODO: other utility functions left over from Addr which may be useful
|
|
|
|
// IsBogon() const;
|
|
|
|
// isPrivate() const;
|
2021-03-09 18:39:40 +00:00
|
|
|
// std::hash
|
2020-05-06 20:38:44 +00:00
|
|
|
// to string / stream / etc
|
|
|
|
|
|
|
|
bool
|
|
|
|
operator<(const IpAddress& other) const;
|
|
|
|
|
|
|
|
bool
|
|
|
|
operator==(const IpAddress& other) const;
|
|
|
|
|
2020-05-04 21:36:08 +00:00
|
|
|
private:
|
2020-05-11 15:47:26 +00:00
|
|
|
bool m_empty = true;
|
2020-05-04 21:36:08 +00:00
|
|
|
std::string m_ipAddress;
|
2020-05-06 20:38:44 +00:00
|
|
|
std::optional<uint16_t> m_port = std::nullopt;
|
2020-05-04 21:17:16 +00:00
|
|
|
};
|
2020-05-06 20:38:44 +00:00
|
|
|
|
|
|
|
std::ostream&
|
|
|
|
operator<<(std::ostream& out, const IpAddress& address);
|
|
|
|
|
2020-05-04 21:17:16 +00:00
|
|
|
} // namespace llarp
|
2021-03-09 18:39:40 +00:00
|
|
|
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
template <>
|
|
|
|
struct hash<llarp::IpAddress>
|
|
|
|
{
|
|
|
|
std::size_t
|
|
|
|
operator()(const llarp::IpAddress& address) const noexcept
|
|
|
|
{
|
|
|
|
return std::hash<std::string>{}(address.toString());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace std
|