ntp: fix handling of socket errors with error queue
In the next Linux version the recvmmsg() system call will be probably fixed to not return socket errors (e.g. due to ICMP) when reading from the error queue. The NTP I/O code assumed this was the correct behavior. When the system call is fixed, a socket error on a client socket will cause chronyd to enter a busy loop consuming the CPU until the receive timeout is reached (8 seconds by default). Use getsockopt(SO_ERROR) to clear the socket error when reading from the error queue failed.
This commit is contained in:
parent
fd1e80802f
commit
19f3ab2225
2 changed files with 15 additions and 1 deletions
14
ntp_io.c
14
ntp_io.c
|
@ -717,6 +717,20 @@ read_from_socket(int sock_fd, int event, void *anything)
|
|||
#endif
|
||||
|
||||
if (status < 0) {
|
||||
#ifdef HAVE_LINUX_TIMESTAMPING
|
||||
/* If reading from the error queue failed, the exception should be
|
||||
for a socket error. Clear the error to avoid a busy loop. */
|
||||
if (flags & MSG_ERRQUEUE) {
|
||||
int error = 0;
|
||||
socklen_t len = sizeof (error);
|
||||
|
||||
if (getsockopt(sock_fd, SOL_SOCKET, SO_ERROR, &error, &len))
|
||||
DEBUG_LOG("Could not get SO_ERROR");
|
||||
if (error)
|
||||
errno = error;
|
||||
}
|
||||
#endif
|
||||
|
||||
DEBUG_LOG("Could not receive from fd %d : %s", sock_fd,
|
||||
strerror(errno));
|
||||
return;
|
||||
|
|
|
@ -497,7 +497,7 @@ SYS_Linux_EnableSystemCallFilter(int level)
|
|||
SCMP_SYS(lseek), SCMP_SYS(rename), SCMP_SYS(stat), SCMP_SYS(stat64),
|
||||
SCMP_SYS(statfs), SCMP_SYS(statfs64), SCMP_SYS(unlink),
|
||||
/* Socket */
|
||||
SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname),
|
||||
SCMP_SYS(bind), SCMP_SYS(connect), SCMP_SYS(getsockname), SCMP_SYS(getsockopt),
|
||||
SCMP_SYS(recvfrom), SCMP_SYS(recvmmsg), SCMP_SYS(recvmsg),
|
||||
SCMP_SYS(sendmmsg), SCMP_SYS(sendmsg), SCMP_SYS(sendto),
|
||||
/* TODO: check socketcall arguments */
|
||||
|
|
Loading…
Reference in a new issue