mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-03 18:35:06 -05:00
socket: add support for socket() flags
On start, check if the SOCK_CLOEXEC and SOCK_NONBLOCK flags are supported in the socket() call and use them instead of fcntl() in order to reduce the number of system calls required to send a client request.
This commit is contained in:
50
socket.c
50
socket.c
@@ -82,6 +82,9 @@ struct MessageHeader {
|
|||||||
|
|
||||||
static int initialised;
|
static int initialised;
|
||||||
|
|
||||||
|
/* Flags supported by socket() */
|
||||||
|
static int socket_flags;
|
||||||
|
|
||||||
/* Arrays of Message and MessageHeader */
|
/* Arrays of Message and MessageHeader */
|
||||||
static ARR_Instance recv_messages;
|
static ARR_Instance recv_messages;
|
||||||
static ARR_Instance recv_headers;
|
static ARR_Instance recv_headers;
|
||||||
@@ -140,12 +143,35 @@ domain_to_string(int domain)
|
|||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_socket_flag(int sock_flag, int fd_flag, int fs_flag)
|
||||||
|
{
|
||||||
|
int sock_fd, fd_flags, fs_flags;
|
||||||
|
|
||||||
|
sock_fd = socket(AF_INET, SOCK_DGRAM | sock_flag, 0);
|
||||||
|
if (sock_fd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fd_flags = fcntl(sock_fd, F_GETFD);
|
||||||
|
fs_flags = fcntl(sock_fd, F_GETFL);
|
||||||
|
|
||||||
|
close(sock_fd);
|
||||||
|
|
||||||
|
if (fd_flags == -1 || (fd_flags & fd_flag) != fd_flag ||
|
||||||
|
fs_flags == -1 || (fs_flags & fs_flag) != fs_flag)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ================================================== */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
open_socket(int domain, int type, int flags)
|
open_socket(int domain, int type, int flags)
|
||||||
{
|
{
|
||||||
int sock_fd;
|
int sock_fd;
|
||||||
|
|
||||||
sock_fd = socket(domain, type, 0);
|
sock_fd = socket(domain, type | socket_flags, 0);
|
||||||
|
|
||||||
if (sock_fd < 0) {
|
if (sock_fd < 0) {
|
||||||
DEBUG_LOG("Could not open %s socket : %s",
|
DEBUG_LOG("Could not open %s socket : %s",
|
||||||
@@ -154,14 +180,22 @@ open_socket(int domain, int type, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Close the socket automatically on exec */
|
/* Close the socket automatically on exec */
|
||||||
if (!UTI_FdSetCloexec(sock_fd)) {
|
if (
|
||||||
|
#ifdef SOCK_CLOEXEC
|
||||||
|
(socket_flags & SOCK_CLOEXEC) == 0 &&
|
||||||
|
#endif
|
||||||
|
!UTI_FdSetCloexec(sock_fd)) {
|
||||||
DEBUG_LOG("Could not set O_CLOEXEC : %s", strerror(errno));
|
DEBUG_LOG("Could not set O_CLOEXEC : %s", strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
return INVALID_SOCK_FD;
|
return INVALID_SOCK_FD;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable non-blocking mode */
|
/* Enable non-blocking mode */
|
||||||
if (fcntl(sock_fd, F_SETFL, O_NONBLOCK)) {
|
if (
|
||||||
|
#ifdef SOCK_NONBLOCK
|
||||||
|
(socket_flags & SOCK_NONBLOCK) == 0 &&
|
||||||
|
#endif
|
||||||
|
fcntl(sock_fd, F_SETFL, O_NONBLOCK)) {
|
||||||
DEBUG_LOG("Could not set O_NONBLOCK : %s", strerror(errno));
|
DEBUG_LOG("Could not set O_NONBLOCK : %s", strerror(errno));
|
||||||
close(sock_fd);
|
close(sock_fd);
|
||||||
return INVALID_SOCK_FD;
|
return INVALID_SOCK_FD;
|
||||||
@@ -943,6 +977,16 @@ SCK_Initialise(void)
|
|||||||
|
|
||||||
priv_bind_function = NULL;
|
priv_bind_function = NULL;
|
||||||
|
|
||||||
|
socket_flags = 0;
|
||||||
|
#ifdef SOCK_CLOEXEC
|
||||||
|
if (check_socket_flag(SOCK_CLOEXEC, FD_CLOEXEC, 0))
|
||||||
|
socket_flags |= SOCK_CLOEXEC;
|
||||||
|
#endif
|
||||||
|
#ifdef SOCK_NONBLOCK
|
||||||
|
if (check_socket_flag(SOCK_NONBLOCK, 0, O_NONBLOCK))
|
||||||
|
socket_flags |= SOCK_NONBLOCK;
|
||||||
|
#endif
|
||||||
|
|
||||||
initialised = 1;
|
initialised = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user