C++ – ipv4 and ipv6 from any valid address

ipv4 and ipv6 from any valid address… here is a solution to the problem.

ipv4 and ipv6 from any valid address

I’m trying to get ipv4 and ipv6 addresses from any string address, be it ipv4, ipv6, or DNS addresses.

I

can create my own function to do this, but I’m trying to use it expert advice And take advantage of built-in features.

There is no way to enter an address in any format string, and have both ipv4 and ipv6 boost address returned?

Solution

Getting an address from a DNS name involves… Query the naming server (DNS!). If you want to enumerate the results, use the parser: in ASIO

Simple example:

#include <boost/asio.hpp>
#include <boost/function_output_iterator.hpp>
#include <set>

using boost::asio::ip::address;

std::set<address> unique_endpoints(std::string const& ip)
{
    using resolver = boost::asio::ip::tcp::resolver;
    boost::asio::io_service ios;  TODO use existing service / resolver
    resolver r(ios);

std::set<address> unique;
    for (auto it = r.resolve({ip, ""}); it != resolver::iterator {}; ++it)
    {
        std::cout << "Resolved: " << it->host_name() << " -> " << it->endpoint() << " " << it->service_name() << "\n";
        address a = it->endpoint().address();
        if (a.is_v4())
            unique.insert(boost::asio::ip::address_v6::v4_mapped(a.to_v4()));
        else
            unique.insert(a);
    }

return unique;
}

template <typename S>
bool endpoints_overlap(S const& a, S const& b)
{
    bool matching_found = false;

std::set_intersection(
            a.begin(), a.end(), b.begin(), b.end(),
            boost::make_function_output_iterator([&](address const&) { matching_found = true; }));

return matching_found;
}

int main()
{
    auto h = unique_endpoints("bbs2.fritz.box");
    auto a = unique_endpoints("192.168.2.111");
    auto b = unique_endpoints("::ffff:192.168.2.111");
    auto c = unique_endpoints("::ffff:c0a8:026f");

assert(endpoints_overlap(a, b));
    assert(endpoints_overlap(a, c));
    assert(endpoints_overlap(b, c));

assert(endpoints_overlap(h, a));
    assert(endpoints_overlap(h, b));
    assert(endpoints_overlap(h, c));
}

Note that when one of the DNS responses matches, this test determines whether the endpoints overlap. This may not always be true in a cluster setup (?) There are no experts there) And you may also want to detect the broadcast address before using this algorithm (not tested).

Also note that I don’t think there’s a way to detect the equivalence of the actual host (meaning that if the host has multiple physical/logical NICs, they will show up as standalone servers for the transport level).

Finally, in a real-world application, you will want asynchronous parsing (using async_resolve).

Related Problems and Solutions