From 4a89ba505930c9e96f297631c2b572a0051df520 Mon Sep 17 00:00:00 2001 From: John Ferlito Date: Sat, 13 Sep 2014 11:24:14 +1000 Subject: [PATCH] Add ReconnectInterval option to Network plugin The Network plugin only performs DNS resolution at initialization. This can be problematic when trying to performs migrations of collectd infrastructure or when trying to create HA solutions which are dependant on DNS. The ReconnectInterval options forces a reconnect of all the sockets at the defined number of seconds. By default no re-connections are attempted if this option is not set. --- src/collectd.conf.in | 1 + src/collectd.conf.pod | 6 ++++++ src/network.c | 24 +++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index 38b2ba46..91c040a3 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -706,6 +706,7 @@ # Username "user" # Password "secret" # Interface "eth0" +# ResolveInterval 14400 @LOAD_PLUGIN_NETWORK@ # TimeToLive "128" # diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index ba99b60d..8ecc92d6 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -3890,6 +3890,12 @@ behavior is to let the kernel choose the appropriate interface. Be warned that the manual selection of an interface for unicast traffic is only necessary in rare cases. +=item B I + +Sets the interval at which to re-resolve the DNS for the I. This is +useful to force a regular DNS lookup to support a high availability setup. If +not specified, re-resolves are never attempted. + =back =item BListen> I [I]B> diff --git a/src/network.c b/src/network.c index 9ad4dead..bf0b2bc6 100644 --- a/src/network.c +++ b/src/network.c @@ -117,6 +117,8 @@ struct sockent_client gcry_cipher_hd_t cypher; unsigned char password_hash[32]; #endif + cdtime_t next_resolve_reconnect; + cdtime_t resolve_interval; }; struct sockent_server @@ -2031,6 +2033,8 @@ static sockent_t *sockent_create (int type) /* {{{ */ { se->data.client.fd = -1; se->data.client.addr = NULL; + se->data.client.resolve_interval = 0; + se->data.client.next_resolve_reconnect = 0; #if HAVE_LIBGCRYPT se->data.client.security_level = SECURITY_LEVEL_NONE; se->data.client.username = NULL; @@ -2125,12 +2129,22 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */ struct addrinfo ai_hints; struct addrinfo *ai_list = NULL, *ai_ptr; int status; + _Bool reconnect = 0; + cdtime_t now; if ((se == NULL) || (se->type != SOCKENT_TYPE_CLIENT)) return (EINVAL); client = &se->data.client; - if (client->fd >= 0) /* already connected */ + + now = cdtime (); + if (client->resolve_interval != 0 && client->next_resolve_reconnect < now) { + DEBUG("network plugin: Reconnecting socket, resolve_interval = %lf, next_resolve_reconnect = %lf", + CDTIME_T_TO_DOUBLE(client->resolve_interval), CDTIME_T_TO_DOUBLE(client->next_resolve_reconnect)); + reconnect = 1; + } + + if (client->fd >= 0 && !reconnect) /* already connected and not stale*/ return (0); memset (&ai_hints, 0, sizeof (ai_hints)); @@ -2162,6 +2176,9 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */ for (ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { + if (client->fd >= 0) /* when we reconnect */ + sockent_client_disconnect(se); + client->fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); @@ -2199,6 +2216,9 @@ static int sockent_client_connect (sockent_t *se) /* {{{ */ freeaddrinfo (ai_list); if (client->fd < 0) return (-1); + + if (client->resolve_interval > 0) + client->next_resolve_reconnect = now + client->resolve_interval; return (0); } /* }}} int sockent_client_connect */ @@ -3209,6 +3229,8 @@ static int network_config_add_server (const oconfig_item_t *ci) /* {{{ */ if (strcasecmp ("Interface", child->key) == 0) network_config_set_interface (child, &se->interface); + else if (strcasecmp ("ResolveInterval", child->key) == 0) + cf_util_get_cdtime(child, &se->data.client.resolve_interval); else { WARNING ("network plugin: Option `%s' is not allowed here.", -- 2.11.0