1968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
2968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* Copyright 1998 by the Massachusetts Institute of Technology.
3968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold *
4968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * Permission to use, copy, modify, and distribute this
5968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software and its documentation for any purpose and without
6968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * fee is hereby granted, provided that the above copyright
7968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice appear in all copies and that both that copyright
8968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * notice and this permission notice appear in supporting
9968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * documentation, and that the name of M.I.T. not be used in
10968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * advertising or publicity pertaining to distribution of the
11968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * software without specific, written prior permission.
12968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * M.I.T. makes no representations about the suitability of
13968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * this software for any purpose.  It is provided "as is"
14968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * without express or implied warranty.
15968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */
16968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
17968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_setup.h"
18968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
19968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#ifdef HAVE_SYS_TIME_H
20968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <sys/time.h>
21968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#endif
22968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
23968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include <time.h>
24968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
25968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares.h"
26968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold#include "ares_private.h"
27968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
28968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold/* WARNING: Beware that this is linear in the number of outstanding
29968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * requests! You are probably far better off just calling ares_process()
30968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * once per second, rather than calling ares_timeout() to figure out
31968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold * when to next call ares_process().
32968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold */
33968bf19396ad404e89420f5d67900fce13f4186cGilad Arnoldstruct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv,
34968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold                             struct timeval *tvbuf)
35968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold{
36968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct query *query;
37968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct list_node* list_head;
38968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct list_node* list_node;
39968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct timeval now;
40968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  struct timeval nextstop;
41968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  long offset, min_offset;
42968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
43968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* No queries, no timeout (and no fetch of the current time). */
44968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (ares__is_list_empty(&(channel->all_queries)))
45968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return maxtv;
46968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
47968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* Find the minimum timeout for the current set of queries. */
48968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  now = ares__tvnow();
49968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  min_offset = -1;
50968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
51968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  list_head = &(channel->all_queries);
52968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  for (list_node = list_head->next; list_node != list_head;
53968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold       list_node = list_node->next)
54968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
55968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      query = list_node->data;
56968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (query->timeout.tv_sec == 0)
57968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        continue;
58968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      offset = ares__timeoffset(&now, &query->timeout);
59968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (offset < 0)
60968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        offset = 0;
61968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      if (min_offset == -1 || offset < min_offset)
62968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold        min_offset = offset;
63968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
64968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
65968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if(min_offset != -1) {
66968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    nextstop.tv_sec = min_offset/1000;
67968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    nextstop.tv_usec = (min_offset%1000)*1000;
68968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  }
69968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold
70968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  /* If we found a minimum timeout and it's sooner than the one specified in
71968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   * maxtv (if any), return it.  Otherwise go with maxtv.
72968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold   */
73968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  if (min_offset != -1 && (!maxtv || ares__timedout(maxtv, &nextstop)))
74968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    {
75968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      *tvbuf = nextstop;
76968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold      return tvbuf;
77968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    }
78968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold  else
79968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold    return maxtv;
80968bf19396ad404e89420f5d67900fce13f4186cGilad Arnold}
81