Bitcoin full node and query server

Feb 13, 2023

View in context in the libbitcoin Slack #general mirror.

evoskuil06:34
// 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]);
}