View in context in the libbitcoin Slack #general mirror.
// C++11: use std::regex.
using namespace boost;
// en.wikipedia.org/wiki/List_of_URI_schemes
// Schemes of p2p network and our zeromq endpoints.
#define SCHEME "(tcp|udp|http|https|inproc):\\/\\/"
#define IPV4 "([0-9.]+)"
#define IPV6 "\\[([0-9a-f:]+)]"
#define HOST "([^:?/\\\\]+)"
#define PORT ":([1-9][0-9]{0,4})"
#define CIDR "\\/([1-9][0-9]{0,2})"
// Excludes ipv4 mapped, unbracketed, and ports allowed by make_address.
bool parse_host(asio::address& ip, const std::string& value) NOEXCEPT
{
static const regex regular
{
"^(" IPV4 "|" IPV6 ")$"
};
sregex_iterator token{ value.begin(), value.end(), regular }, end{};
return token != end
&& make_address(ip, (*token)[1]);
}
// Excludes ipv4 mapped to ipv6.
bool parse_authority(asio::address& ip, uint16_t& port, uint8_t& cidr,
const std::string& value) NOEXCEPT
{
static const regex regular
{
"^(" IPV4 "|" IPV6 ")(" PORT ")?(" CIDR ")?$"
};
sregex_iterator token{ value.begin(), value.end(), regular }, end{};
return token != end
&& make_address(ip, (*token)[1])
&& to_integer(port, (*token)[5])
&& to_integer(cidr, (*token)[7])
&& ((ip.is_v4() && cidr <= maximum_cidr_ip4) ||
(ip.is_v6() && cidr <= maximum_cidr_ip6));
}
// Excludes ipv4 mapped to ipv6.
bool parse_endpoint(std::string& scheme, std::string& host, uint16_t& port,
const std::string& value) NOEXCEPT
{
static const regex regular
{
"^(" SCHEME ")?(" IPV4 "|" IPV6 "|" HOST ")(" PORT ")?$"
};
sregex_iterator token{ value.begin(), value.end(), regular }, end{};
return token != end
&& to_string(scheme, (*token)[2])
&& to_string(host, (*token)[3])
&& to_integer(port, (*token)[8]);
}