From 33d79024cf9dc514608883f704dd40ee5e41f008 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Wed, 15 Aug 2018 12:21:36 +0200 Subject: [PATCH] chrony: Ignore late responses If a response from chronyd was not received before the timeout (e.g. on a busy system), it would wait in the receive queue and be processed as a response of the next request. It would fail the sequence check and cause the plugin to return with an error. The latest response would wait in the receive queue and this would repeat forever. Flush the receive queue before sending a new batch of requests to prevent this situation from happening. --- src/chrony.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/chrony.c b/src/chrony.c index 6fb369a2..913aab94 100644 --- a/src/chrony.c +++ b/src/chrony.c @@ -38,6 +38,11 @@ #include /* ntohs/ntohl */ #endif +/* AIX doesn't have MSG_DONTWAIT */ +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + #define CONFIG_KEY_HOST "Host" #define CONFIG_KEY_PORT "Port" #define CONFIG_KEY_TIMEOUT "Timeout" @@ -440,6 +445,15 @@ static int chrony_recv_response(tChrony_Response *p_resp, } } +static void chrony_flush_recv_queue(void) { + char buf[1]; + + if (g_chrony_is_connected) { + while (recv(g_chrony_socket, buf, sizeof(buf), MSG_DONTWAIT) > 0) + ; + } +} + static int chrony_query(const int p_command, tChrony_Request *p_req, tChrony_Response *p_resp, size_t *p_resp_size) { /* Check connection. We simply perform one try as collectd already handles @@ -964,6 +978,9 @@ static int chrony_read(void) { g_chrony_seq_is_initialized = 1; } + /* Ignore late responses that may have been received */ + chrony_flush_recv_queue(); + /* Get daemon stats */ rc = chrony_request_daemon_stats(); if (rc != CHRONY_RC_OK) -- 2.11.0