As per the boost documentation - https://www.boost.org/doc/libs/1_75_0/doc/html/boost_asio/reference/ip__udp/socket.html, the ip::udp::socket is not thread-safe for shared objects.
However if we look at the underlying UNIX APIs for socket programming, recv() on a SOCK_DGRAM socket is thread-safe. We know this because a list o unsafe operation is documented here - https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09 and recv() is not there.
It's because accessing the object from different threads would constitute a data race.
The same would be true for your file-descriptor in the posix API. This is a common source for ludicrous bugs like ABA problem on closed/reused file descriptors.
Finally, note that if the class
it might very well actually be safe to use these IO objects without synchronization. It's just that the documentation does not guarantee that.
This is good practice/good library design: you have an interface contract where the guarantees are documented. The rest is implementation details. The implementation details may change over time, and you cannot afford to recheck each update whether your extra "assumed guarantees" still hold.