From 69103d62ec08b0261c313d68616c28a88a7fc8bd Mon Sep 17 00:00:00 2001 From: "Brett T. Warden" Date: Mon, 17 Oct 2022 13:50:10 -0700 Subject: [PATCH] Wait up to 100 seconds for hostname lookup In case networking takes as long as a minute to come up, give hostname lookup up to 100 seconds to complete. Give initial HTTP request up to 120 seconds _from when we started_ to succeed, so even if we spent all our time waiting on DNS, we still give 20 more seconds for the HTTP server. --- src/ucd-data-fetch.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/ucd-data-fetch.c b/src/ucd-data-fetch.c index 4aa3517..6736dbc 100644 --- a/src/ucd-data-fetch.c +++ b/src/ucd-data-fetch.c @@ -266,22 +266,40 @@ int main(int argc, char *argv[]) { server.sin_addr.s_addr = inet_addr(config[conf].ip); server.sin_port = htons(config[conf].port); + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50000000; + /* Do we need to look up a hostname? */ if ((int) server.sin_addr.s_addr == -1) { - struct hostent *hp = gethostbyname(config[conf].ip); - if (!hp || hp->h_length <= 0) { - FAIL("gethostbyname()"); - } + n = 0; + for (;;) { + struct hostent *hp = gethostbyname(config[conf].ip); + if (hp != NULL) { + if (hp->h_length > 0) { + /* Got it; use the resulting IP address */ + server.sin_family = (short unsigned int) (hp->h_addrtype & 0xFFFF); + memcpy(&(server.sin_addr.s_addr), hp->h_addr, (size_t) hp->h_length); + break; + } + else { + fprintf(stderr, "gethostbyname(): empty response"); + exit(EXIT_FAILURE); + } + } - /* Got it; use the resulting IP address */ - server.sin_family = (short unsigned int) (hp->h_addrtype & 0xFFFF); - memcpy(&(server.sin_addr.s_addr), hp->h_addr, (size_t) hp->h_length); + if ((h_errno != TRY_AGAIN) && (h_errno != NO_RECOVERY)) { + herror("gethostbyname()"); + exit(EXIT_FAILURE); + } + nanosleep(&ts, NULL); + if (++n > 2000) { /* 100 secs */ + herror("gethostbyname()"); + exit(EXIT_FAILURE); + } + } } - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 50000000; - for (;;) { int r = connect(sockfd, (struct sockaddr *)&server, sizeof(server)); if (r == 0) { @@ -291,7 +309,7 @@ int main(int argc, char *argv[]) { FAIL("connect()"); } nanosleep(&ts, NULL); - if (++n > 200) { /* 10 secs */ + if (++n > 2400) { /* 120 secs - any used up in gethostbyname */ FAIL("timeout in connect()"); } }