aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/ntp/libntp/ntp_intres.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/ntp_intres.c')
-rw-r--r--contrib/ntp/libntp/ntp_intres.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/contrib/ntp/libntp/ntp_intres.c b/contrib/ntp/libntp/ntp_intres.c
index 0b5bb7534256..7aa288af57b2 100644
--- a/contrib/ntp/libntp/ntp_intres.c
+++ b/contrib/ntp/libntp/ntp_intres.c
@@ -118,14 +118,16 @@
* is managed by the code which calls the *_complete routines.
*/
+
/* === typedefs === */
typedef struct blocking_gai_req_tag { /* marshalled args */
size_t octets;
u_int dns_idx;
time_t scheduled;
time_t earliest;
- struct addrinfo hints;
int retry;
+ struct addrinfo hints;
+ u_int qflags;
gai_sometime_callback callback;
void * context;
size_t nodesize;
@@ -205,8 +207,8 @@ static dnsworker_ctx * get_worker_context(blocking_child *, u_int);
static void scheduled_sleep(time_t, time_t,
dnsworker_ctx *);
static void manage_dns_retry_interval(time_t *, time_t *,
- int *,
- time_t *);
+ int *, time_t *,
+ int/*BOOL*/);
static int should_retry_dns(int, int);
#ifdef HAVE_RES_INIT
static void reload_resolv_conf(dnsworker_ctx *);
@@ -230,13 +232,14 @@ static void getnameinfo_sometime_complete(blocking_work_req,
* invokes provided callback completion function.
*/
int
-getaddrinfo_sometime(
+getaddrinfo_sometime_ex(
const char * node,
const char * service,
const struct addrinfo * hints,
int retry,
gai_sometime_callback callback,
- void * context
+ void * context,
+ u_int qflags
)
{
blocking_gai_req * gai_req;
@@ -277,6 +280,7 @@ getaddrinfo_sometime(
gai_req->context = context;
gai_req->nodesize = nodesize;
gai_req->servsize = servsize;
+ gai_req->qflags = qflags;
memcpy((char *)gai_req + sizeof(*gai_req), node, nodesize);
memcpy((char *)gai_req + sizeof(*gai_req) + nodesize, service,
@@ -451,6 +455,20 @@ blocking_getaddrinfo(
return 0;
}
+int
+getaddrinfo_sometime(
+ const char * node,
+ const char * service,
+ const struct addrinfo * hints,
+ int retry,
+ gai_sometime_callback callback,
+ void * context
+ )
+{
+ return getaddrinfo_sometime_ex(node, service, hints, retry,
+ callback, context, 0);
+}
+
static void
getaddrinfo_sometime_complete(
@@ -470,7 +488,7 @@ getaddrinfo_sometime_complete(
char * service;
char * canon_start;
time_t time_now;
- int again;
+ int again, noerr;
int af;
const char * fam_spec;
int i;
@@ -498,8 +516,9 @@ getaddrinfo_sometime_complete(
gai_req->dns_idx, humantime(time_now)));
}
} else {
- again = should_retry_dns(gai_resp->retcode,
- gai_resp->gai_errno);
+ noerr = !!(gai_req->qflags & GAIR_F_IGNDNSERR);
+ again = noerr || should_retry_dns(
+ gai_resp->retcode, gai_resp->gai_errno);
/*
* exponential backoff of DNS retries to 64s
*/
@@ -528,9 +547,10 @@ getaddrinfo_sometime_complete(
gai_strerror(gai_resp->retcode),
gai_resp->retcode);
}
- manage_dns_retry_interval(&gai_req->scheduled,
- &gai_req->earliest, &gai_req->retry,
- &child_ctx->next_dns_timeslot);
+ manage_dns_retry_interval(
+ &gai_req->scheduled, &gai_req->earliest,
+ &gai_req->retry, &child_ctx->next_dns_timeslot,
+ noerr);
if (!queue_blocking_request(
BLOCKING_GETADDRINFO,
gai_req,
@@ -826,7 +846,7 @@ getnameinfo_sometime_complete(
if (gni_req->retry > 0)
manage_dns_retry_interval(&gni_req->scheduled,
&gni_req->earliest, &gni_req->retry,
- &child_ctx->next_dns_timeslot);
+ &child_ctx->next_dns_timeslot, FALSE);
if (gni_req->retry > 0 && again) {
if (!queue_blocking_request(
@@ -1033,18 +1053,32 @@ manage_dns_retry_interval(
time_t * pscheduled,
time_t * pwhen,
int * pretry,
- time_t * pnext_timeslot
+ time_t * pnext_timeslot,
+ int forever
)
{
time_t now;
time_t when;
int retry;
+ int retmax;
now = time(NULL);
retry = *pretry;
when = max(now + retry, *pnext_timeslot);
*pnext_timeslot = when;
- retry = min(64, retry << 1);
+
+ /* this exponential backoff is slower than doubling up: The
+ * sequence goes 2-3-4-6-8-12-16-24-32... and the upper limit is
+ * 64 seconds for things that should not repeat forever, and
+ * 1024 when repeated forever.
+ */
+ retmax = forever ? 1024 : 64;
+ retry <<= 1;
+ if (retry & (retry - 1))
+ retry &= (retry - 1);
+ else
+ retry -= (retry >> 2);
+ retry = min(retmax, retry);
*pscheduled = now;
*pwhen = when;