chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.81k stars 1.2k forks source link

feature request: build endpoint from sockaddr* #1300

Open aberaud opened 1 year ago

aberaud commented 1 year ago

I've been converting UNIX code to ASIO C++, and one of the most significant friction point is that there seem to be no simple way to build asio::ip::udp::endpoint or asio::ip::tcp::endpoint from the standard struct sockaddr*.

This is a pain-point when interfacing ASIO code with C libraries or other parts of the code that use struct sockaddr*.

I've been generating the following conversion routine with ChatGPT (see bellow), but it seems bug-prone and inefficient. It seems like the standard struct sockaddr is supported on every platform supported by ASIO ? So it might be possible to have conversion routines from struct sockaddr part of ASIO ? Or is it something that already exists and that I've been missing ? Many thanks.

asio::ip::udp::endpoint
sockaddr_to_endpoint(struct sockaddr* addr) {
    if (addr->sa_family == AF_INET) {
        auto addr_in = reinterpret_cast<struct sockaddr_in*>(addr);
        asio::ip::address_v4 address(ntohl(addr_in->sin_addr.s_addr));
        unsigned short port = ntohs(addr_in->sin_port);
        return asio::ip::udp::endpoint(address, port);
    } else if (addr->sa_family == AF_INET6) {
        auto addr_in6 = reinterpret_cast<struct sockaddr_in6*>(addr);
        asio::ip::address_v6::bytes_type bytes;
        std::memcpy(bytes.data(), &addr_in6->sin6_addr, 16);
        asio::ip::address_v6 address(bytes, addr_in6->sin6_scope_id);
        unsigned short port = ntohs(addr_in6->sin6_port);
        return asio::ip::udp::endpoint(address, port);
    } else {
        throw std::runtime_error("Invalid sockaddr family");
    }
}
andrei-datcu commented 1 year ago

https://think-async.com/Asio/asio-1.28.0/doc/asio/reference/ip__basic_endpoint/data.html

aberaud commented 1 year ago

https://think-async.com/Asio/asio-1.28.0/doc/asio/reference/ip__basic_endpoint/data.html

Thanks a lot ! This solves half of the issue, as it converts to sockaddr.

aberaud commented 2 months ago

Any update ? data() provides access to the native type but there is no clean/official way to convert from a native address type to an asio endpoint.

I've seen so many different / custom code to achieve this, it's a major waste of time and cause of bugs.