|
24 | 24 | #define WOLFSSL_STRERROR_BUFFER_SIZE 256 |
25 | 25 | #endif |
26 | 26 |
|
| 27 | +/* Enable GNU extensions for accept4() on Linux/glibc. Must be defined |
| 28 | + * before any system headers are included. Excluded for Zephyr and other |
| 29 | + * embedded RTOSes whose libc layers conflict with glibc-style definitions |
| 30 | + * (e.g., Zephyr's socket_select.h vs. glibc's fd_set). */ |
| 31 | +#if (defined(__linux__) || defined(__ANDROID__)) && \ |
| 32 | + !defined(WOLFSSL_ZEPHYR) && !defined(_GNU_SOURCE) |
| 33 | + #define _GNU_SOURCE 1 |
| 34 | +#endif |
| 35 | + |
27 | 36 | #include <wolfssl/wolfcrypt/libwolfssl_sources.h> |
28 | 37 |
|
29 | 38 | #ifndef WOLFCRYPT_ONLY |
|
42 | 51 | #include <wolfssl/wolfio.h> |
43 | 52 | #include <wolfssl/wolfcrypt/logging.h> |
44 | 53 |
|
| 54 | +/* SOCK_CLOEXEC sets close-on-exec atomically when the socket is created; |
| 55 | + * fall back to a no-op flag value where it isn't supported. */ |
| 56 | +#ifndef SOCK_CLOEXEC |
| 57 | + #define SOCK_CLOEXEC 0 |
| 58 | +#endif |
| 59 | + |
45 | 60 | #ifdef NUCLEUS_PLUS_2_3 |
46 | 61 | /* Holds last Nucleus networking error number */ |
47 | 62 | int Nucleus_Net_Errno; |
@@ -1494,7 +1509,17 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) |
1494 | 1509 | } |
1495 | 1510 | #endif |
1496 | 1511 |
|
1497 | | - *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0); |
| 1512 | + *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 1513 | +#if !defined(USE_WINDOWS_API) && defined(FD_CLOEXEC) |
| 1514 | + if (*sockfd <= SOCKET_INVALID && errno == EINVAL) { |
| 1515 | + *sockfd = (SOCKET_T)socket(addr.ss_family, SOCK_STREAM, 0); |
| 1516 | + if (*sockfd > SOCKET_INVALID) { |
| 1517 | + int fdFlags = fcntl(*sockfd, F_GETFD); |
| 1518 | + if (fdFlags >= 0) |
| 1519 | + (void)fcntl(*sockfd, F_SETFD, fdFlags | FD_CLOEXEC); |
| 1520 | + } |
| 1521 | + } |
| 1522 | +#endif |
1498 | 1523 | #ifdef USE_WINDOWS_API |
1499 | 1524 | if (*sockfd == SOCKET_INVALID) |
1500 | 1525 | #else |
@@ -1572,12 +1597,32 @@ int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port) |
1572 | 1597 | sin->sin6_family = AF_INET6; |
1573 | 1598 | sin->sin6_addr = in6addr_any; |
1574 | 1599 | sin->sin6_port = XHTONS(port); |
1575 | | - *sockfd = (SOCKET_T)socket(AF_INET6, SOCK_STREAM, 0); |
| 1600 | + *sockfd = (SOCKET_T)socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 1601 | +#if defined(FD_CLOEXEC) |
| 1602 | + if (*sockfd <= SOCKET_INVALID && errno == EINVAL) { |
| 1603 | + *sockfd = (SOCKET_T)socket(AF_INET6, SOCK_STREAM, 0); |
| 1604 | + if (*sockfd > SOCKET_INVALID) { |
| 1605 | + int fdFlags = fcntl(*sockfd, F_GETFD); |
| 1606 | + if (fdFlags >= 0) |
| 1607 | + (void)fcntl(*sockfd, F_SETFD, fdFlags | FD_CLOEXEC); |
| 1608 | + } |
| 1609 | + } |
| 1610 | +#endif |
1576 | 1611 | #else |
1577 | 1612 | sin->sin_family = AF_INET; |
1578 | 1613 | sin->sin_addr.s_addr = INADDR_ANY; |
1579 | 1614 | sin->sin_port = XHTONS(port); |
1580 | | - *sockfd = (SOCKET_T)socket(AF_INET, SOCK_STREAM, 0); |
| 1615 | + *sockfd = (SOCKET_T)socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 1616 | +#if defined(FD_CLOEXEC) |
| 1617 | + if (*sockfd <= SOCKET_INVALID && errno == EINVAL) { |
| 1618 | + *sockfd = (SOCKET_T)socket(AF_INET, SOCK_STREAM, 0); |
| 1619 | + if (*sockfd > SOCKET_INVALID) { |
| 1620 | + int fdFlags = fcntl(*sockfd, F_GETFD); |
| 1621 | + if (fdFlags >= 0) |
| 1622 | + (void)fcntl(*sockfd, F_SETFD, fdFlags | FD_CLOEXEC); |
| 1623 | + } |
| 1624 | + } |
| 1625 | +#endif |
1581 | 1626 | #endif |
1582 | 1627 |
|
1583 | 1628 | #ifdef USE_WINDOWS_API |
@@ -1623,7 +1668,31 @@ int wolfIO_TcpBind(SOCKET_T* sockfd, word16 port) |
1623 | 1668 | #ifdef HAVE_SOCKADDR |
1624 | 1669 | int wolfIO_TcpAccept(SOCKET_T sockfd, SOCKADDR* peer_addr, XSOCKLENT* peer_len) |
1625 | 1670 | { |
1626 | | - return (int)accept(sockfd, peer_addr, peer_len); |
| 1671 | + int fd; |
| 1672 | +#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_ZEPHYR) && \ |
| 1673 | + (defined(__linux__) || defined(__ANDROID__)) |
| 1674 | + fd = (int)accept4(sockfd, peer_addr, peer_len, SOCK_CLOEXEC); |
| 1675 | + if (fd < 0 && (errno == ENOSYS || errno == EINVAL)) { |
| 1676 | + fd = (int)accept(sockfd, peer_addr, peer_len); |
| 1677 | + #ifdef FD_CLOEXEC |
| 1678 | + if (fd >= 0) { |
| 1679 | + int fdFlags = fcntl(fd, F_GETFD); |
| 1680 | + if (fdFlags >= 0) |
| 1681 | + (void)fcntl(fd, F_SETFD, fdFlags | FD_CLOEXEC); |
| 1682 | + } |
| 1683 | + #endif |
| 1684 | + } |
| 1685 | +#else |
| 1686 | + fd = (int)accept(sockfd, peer_addr, peer_len); |
| 1687 | +#if defined(FD_CLOEXEC) && !defined(USE_WINDOWS_API) |
| 1688 | + if (fd >= 0) { |
| 1689 | + int fdFlags = fcntl(fd, F_GETFD); |
| 1690 | + if (fdFlags >= 0) |
| 1691 | + (void)fcntl(fd, F_SETFD, fdFlags | FD_CLOEXEC); |
| 1692 | + } |
| 1693 | +#endif |
| 1694 | +#endif |
| 1695 | + return fd; |
1627 | 1696 | } |
1628 | 1697 | #endif /* HAVE_SOCKADDR */ |
1629 | 1698 |
|
|
0 commit comments