• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 1998 Massachusetts Institute of Technology
4  * Copyright (c) The c-ares project and its contributors
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * SPDX-License-Identifier: MIT
26  */
27 
28 #include "ares_setup.h"
29 
30 #ifdef HAVE_LIMITS_H
31 #  include <limits.h>
32 #endif
33 
34 #include "ares.h"
35 #include "ares_private.h"
36 
ares__timeval_remaining(struct timeval * remaining,const struct timeval * now,const struct timeval * tout)37 void ares__timeval_remaining(struct timeval       *remaining,
38                              const struct timeval *now,
39                              const struct timeval *tout)
40 {
41   memset(remaining, 0, sizeof(*remaining));
42 
43   /* Expired! */
44   if (tout->tv_sec < now->tv_sec ||
45       (tout->tv_sec == now->tv_sec && tout->tv_usec < now->tv_usec)) {
46     return;
47   }
48 
49   remaining->tv_sec = tout->tv_sec - now->tv_sec;
50   if (tout->tv_usec < now->tv_usec) {
51     remaining->tv_sec  -= 1;
52     remaining->tv_usec  = (tout->tv_usec + 1000000) - now->tv_usec;
53   } else {
54     remaining->tv_usec = tout->tv_usec - now->tv_usec;
55   }
56 }
57 
ares_timeout(ares_channel_t * channel,struct timeval * maxtv,struct timeval * tvbuf)58 struct timeval *ares_timeout(ares_channel_t *channel, struct timeval *maxtv,
59                              struct timeval *tvbuf)
60 {
61   const struct query *query;
62   ares__slist_node_t *node;
63   struct timeval      now;
64 
65   /* The minimum timeout of all queries is always the first entry in
66    * channel->queries_by_timeout */
67   node = ares__slist_node_first(channel->queries_by_timeout);
68   /* no queries/timeout */
69   if (node == NULL) {
70     return maxtv; /* <-- maxtv can be null though, hrm */
71   }
72 
73   query = ares__slist_node_val(node);
74 
75   now = ares__tvnow();
76 
77   ares__timeval_remaining(tvbuf, &now, &query->timeout);
78 
79   if (maxtv == NULL) {
80     return tvbuf;
81   }
82 
83   /* Return the minimum time between maxtv and tvbuf */
84 
85   if (tvbuf->tv_sec > maxtv->tv_sec) {
86     return maxtv;
87   }
88   if (tvbuf->tv_sec < maxtv->tv_sec) {
89     return tvbuf;
90   }
91 
92   if (tvbuf->tv_usec > maxtv->tv_usec) {
93     return maxtv;
94   }
95 
96   return tvbuf;
97 }
98