ntf-core icon indicating copy to clipboard operation
ntf-core copied to clipboard

`ntsi::StreamSocket::bind` parameter `reuseAddress` is inconsistent on different platforms

Open che2 opened this issue 8 months ago • 0 comments

The behavior of the method seems to be different on AIX and Linux:

    auto err = socket1->bind(ntsa::Endpoint(ntsa::Ipv4Endpoint("127.0.0.1", 0)), true);
    assert(!err);

    ntsa::Endpoint endpoint;
    socket->sourceEndpoint(&endpoint);

    err = socket2->bind(ntsa::Endpoint(ntsa::Ipv4Endpoint("127.0.0.1", 0)), true);
    assert(!err);
    // on AIX the second bind succeeds, while on Linux this fails.

I attached the relevant code in ntsu_socketoptionutil.cpp below. I think SO_REUSEPORT is required for the above code to work on Linux. I understand making the behavior consistent on all support platform might be very difficult or impossible, so it's not a straight forward fix.

ntsa::Error SocketOptionUtil::setReuseAddress(ntsa::Handle socket,
                                              bool         reuseAddress)
{
    {
        int optionValue = static_cast<int>(reuseAddress);

        int rc = setsockopt(socket,
                            SOL_SOCKET,
                            SO_REUSEADDR,
                            reinterpret_cast<char*>(&optionValue),
                            sizeof(optionValue));

        if (rc != 0) {
            return ntsa::Error(errno);
        }
    }

#if defined(BSLS_PLATFORM_OS_AIX) || defined(BSLS_PLATFORM_OS_DARWIN) ||      \
    defined(BSLS_PLATFORM_OS_FREEBSD)

    {
        int optionValue = static_cast<int>(reuseAddress);

        int rc = setsockopt(socket,
                            SOL_SOCKET,
                            SO_REUSEPORT,
                            reinterpret_cast<char*>(&optionValue),
                            sizeof(optionValue));

        if (rc != 0) {
            return ntsa::Error(errno);
        }
    }

#endif

    return ntsa::Error();
}

che2 avatar Jun 12 '24 18:06 che2