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