mirror of
https://github.com/curl/curl.git
synced 2026-04-14 22:01:41 +03:00
socket: use accept4 when available
Linux, *BSD, and Solaris support accept4 system call that enables the caller to assign additional flags and save some extra system calls. It can come in handy when O_NONBLOCK or/and FD_CLOEXEC is/are required on a socket after being accepted. Ref: https://man7.org/linux/man-pages/man2/accept.2.html https://man.freebsd.org/cgi/man.cgi?query=accept4 https://man.dragonflybsd.org/?command=accept§ion=2 https://man.openbsd.org/accept.2 https://man.netbsd.org/accept.2 https://docs.oracle.com/cd/E88353_01/html/E37843/accept4-3c.html https://www.gnu.org/software/gnulib/manual/html_node/accept4.html Closes #16979
This commit is contained in:
parent
2f5e4e0db4
commit
3d02872be7
8 changed files with 52 additions and 2 deletions
|
|
@ -26,6 +26,15 @@ if(NOT UNIX)
|
|||
message(FATAL_ERROR "This file should be included on Unix platforms only")
|
||||
endif()
|
||||
|
||||
if(APPLE OR
|
||||
CYGWIN)
|
||||
set(HAVE_ACCEPT4 0)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR
|
||||
CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
|
||||
set(HAVE_ACCEPT4 1)
|
||||
endif()
|
||||
set(HAVE_ALARM 1)
|
||||
if(ANDROID)
|
||||
set(HAVE_ARC4RANDOM 1)
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ else()
|
|||
set(HAVE_ATOMIC 0)
|
||||
endif()
|
||||
|
||||
set(HAVE_ACCEPT4 0)
|
||||
set(HAVE_ALARM 0)
|
||||
set(HAVE_ARC4RANDOM 0)
|
||||
set(HAVE_ARPA_INET_H 0)
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ endif()
|
|||
include(PickyWarnings)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
string(APPEND CMAKE_C_FLAGS " -D_GNU_SOURCE") # Required for sendmmsg()
|
||||
string(APPEND CMAKE_C_FLAGS " -D_GNU_SOURCE") # Required for sendmmsg() and accept4()
|
||||
endif()
|
||||
|
||||
option(ENABLE_DEBUG "Enable curl debug features (for developing curl itself)" OFF)
|
||||
|
|
@ -1732,6 +1732,7 @@ elseif(DOS)
|
|||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${WATT_ROOT}/lib/libwatt.a")
|
||||
endif()
|
||||
|
||||
check_function_exists("accept4" HAVE_ACCEPT4)
|
||||
check_function_exists("fnmatch" HAVE_FNMATCH)
|
||||
check_symbol_exists("basename" "${CURL_INCLUDES};string.h" HAVE_BASENAME) # libgen.h unistd.h
|
||||
check_symbol_exists("opendir" "dirent.h" HAVE_OPENDIR)
|
||||
|
|
|
|||
|
|
@ -574,7 +574,7 @@ esac
|
|||
|
||||
AM_CONDITIONAL(BUILD_UNITTESTS, test x$supports_unittests = xyes)
|
||||
|
||||
# In order to detect support of sendmmsg(), we need to escape the POSIX
|
||||
# In order to detect support of sendmmsg() and accept4(), we need to escape the POSIX
|
||||
# jail by defining _GNU_SOURCE or <sys/socket.h> will not expose it.
|
||||
case $host_os in
|
||||
linux*)
|
||||
|
|
@ -4112,6 +4112,7 @@ case $host in
|
|||
esac
|
||||
|
||||
AC_CHECK_FUNCS([\
|
||||
accept4 \
|
||||
eventfd \
|
||||
fnmatch \
|
||||
geteuid \
|
||||
|
|
|
|||
|
|
@ -2144,7 +2144,12 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
|||
|
||||
if(0 == getsockname(ctx->sock, (struct sockaddr *) &add, &size)) {
|
||||
size = sizeof(add);
|
||||
#ifdef HAVE_ACCEPT4
|
||||
s_accepted = accept4(ctx->sock, (struct sockaddr *) &add, &size,
|
||||
SOCK_NONBLOCK | SOCK_CLOEXEC);
|
||||
#else
|
||||
s_accepted = accept(ctx->sock, (struct sockaddr *) &add, &size);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(CURL_SOCKET_BAD == s_accepted) {
|
||||
|
|
@ -2153,7 +2158,9 @@ static CURLcode cf_tcp_accept_connect(struct Curl_cfilter *cf,
|
|||
}
|
||||
|
||||
infof(data, "Connection accepted from server");
|
||||
#ifndef HAVE_ACCEPT4
|
||||
(void)curlx_nonblock(s_accepted, TRUE); /* enable non-blocking */
|
||||
#endif
|
||||
/* Replace any filter on SECONDARY with one listening on this socket */
|
||||
ctx->listening = FALSE;
|
||||
ctx->accepted = TRUE;
|
||||
|
|
|
|||
|
|
@ -197,6 +197,9 @@
|
|||
/* Define to 1 if you have _Atomic support. */
|
||||
#cmakedefine HAVE_ATOMIC 1
|
||||
|
||||
/* Define to 1 if you have the `accept4' function. */
|
||||
#cmakedefine HAVE_ACCEPT4 1
|
||||
|
||||
/* Define to 1 if you have the `fnmatch' function. */
|
||||
#cmakedefine HAVE_FNMATCH 1
|
||||
|
||||
|
|
|
|||
|
|
@ -378,6 +378,24 @@ curl_socket_t curl_dbg_accept(curl_socket_t s, void *saddr, void *saddrlen,
|
|||
return sockfd;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ACCEPT4
|
||||
curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr, void *saddrlen,
|
||||
int flags,
|
||||
int line, const char *source)
|
||||
{
|
||||
struct sockaddr *addr = (struct sockaddr *)saddr;
|
||||
curl_socklen_t *addrlen = (curl_socklen_t *)saddrlen;
|
||||
|
||||
curl_socket_t sockfd = accept4(s, addr, addrlen, flags);
|
||||
|
||||
if(source && (sockfd != CURL_SOCKET_BAD))
|
||||
curl_dbg_log("FD %s:%d accept() = %" FMT_SOCKET_T "\n",
|
||||
source, line, sockfd);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* separate function to allow libcurl to mark a "faked" close */
|
||||
void curl_dbg_mark_sclose(curl_socket_t sockfd, int line, const char *source)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ CURL_EXTERN int curl_dbg_sclose(curl_socket_t sockfd,
|
|||
int line, const char *source);
|
||||
CURL_EXTERN curl_socket_t curl_dbg_accept(curl_socket_t s, void *a, void *alen,
|
||||
int line, const char *source);
|
||||
#ifdef HAVE_ACCEPT4
|
||||
CURL_EXTERN curl_socket_t curl_dbg_accept4(curl_socket_t s, void *saddr,
|
||||
void *saddrlen, int flags,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
CURL_EXTERN int curl_dbg_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socket_vector[2],
|
||||
|
|
@ -159,6 +164,11 @@ CURL_EXTERN ALLOC_FUNC
|
|||
#undef accept /* for those with accept as a macro */
|
||||
#define accept(sock,addr,len)\
|
||||
curl_dbg_accept(sock, addr, len, __LINE__, __FILE__)
|
||||
#ifdef HAVE_ACCEPT4
|
||||
#undef accept4 /* for those with accept4 as a macro */
|
||||
#define accept4(sock,addr,len,flags)\
|
||||
curl_dbg_accept4(sock, addr, len, flags, __LINE__, __FILE__)
|
||||
#endif
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#define socketpair(domain,type,protocol,socket_vector)\
|
||||
curl_dbg_socketpair((int)domain, type, protocol, socket_vector, \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue