TLA Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
3 : //
4 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // Official repository: https://github.com/cppalliance/corosio
8 : //
9 :
10 : #ifndef BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
11 : #define BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
12 :
13 : #include <boost/corosio/detail/platform.hpp>
14 :
15 : #if BOOST_COROSIO_POSIX
16 :
17 : #include <boost/corosio/native/detail/make_err.hpp>
18 :
19 : #include <cerrno>
20 : #include <system_error>
21 :
22 : #include <sys/socket.h>
23 :
24 : namespace boost::corosio::detail {
25 :
26 : /** Validate a caller-supplied socket fd for adoption.
27 :
28 : Non-mutating: interrogates the fd without changing any of its
29 : flags, so a rejected fd goes back to the caller untouched.
30 :
31 : @param fd The descriptor to validate.
32 : @param expected_type `SOCK_STREAM` or `SOCK_DGRAM`.
33 : @param is_ip Accept `AF_INET`/`AF_INET6` when true, `AF_UNIX`
34 : when false.
35 : @return Empty on success; `EBADF`, `EAFNOSUPPORT`, `EPROTOTYPE`,
36 : or the `errno` reported by the interrogating call.
37 : */
38 : inline std::error_code
39 HIT 274 : validate_socket_fd(int fd, int expected_type, bool is_ip) noexcept
40 : {
41 274 : if (fd < 0)
42 14 : return make_err(EBADF);
43 :
44 260 : sockaddr_storage st{};
45 260 : socklen_t st_len = sizeof(st);
46 260 : if (::getsockname(fd, reinterpret_cast<sockaddr*>(&st), &st_len) != 0)
47 MIS 0 : return make_err(errno);
48 HIT 260 : if (is_ip)
49 : {
50 38 : if (st.ss_family != AF_INET && st.ss_family != AF_INET6)
51 6 : return make_err(EAFNOSUPPORT);
52 : }
53 222 : else if (st.ss_family != AF_UNIX)
54 : {
55 2 : return make_err(EAFNOSUPPORT);
56 : }
57 :
58 252 : int sock_type = 0;
59 252 : socklen_t opt_len = sizeof(sock_type);
60 252 : if (::getsockopt(fd, SOL_SOCKET, SO_TYPE,
61 252 : &sock_type, &opt_len) != 0)
62 MIS 0 : return make_err(errno);
63 HIT 252 : if (sock_type != expected_type)
64 18 : return make_err(EPROTOTYPE);
65 :
66 234 : return {};
67 : }
68 :
69 : } // namespace boost::corosio::detail
70 :
71 : #endif // BOOST_COROSIO_POSIX
72 :
73 : #endif // BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
|