]> git.ipfire.org Git - thirdparty/glibc.git/blame - resolv/res_send.c
resolv: Deprecate RES_BLAST
[thirdparty/glibc.git] / resolv / res_send.c
CommitLineData
e9db92d3
CD
1/* Copyright (C) 2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
17
28f540f4 18/*
28f540f4
RM
19 * Copyright (c) 1985, 1989, 1993
20 * The Regents of the University of California. All rights reserved.
e62b2105 21 *
28f540f4
RM
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the above copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
28f540f4
RM
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
e62b2105 33 *
28f540f4
RM
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
b43b13ac
UD
45 */
46
47/*
28f540f4 48 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
e62b2105 49 *
28f540f4
RM
50 * Permission to use, copy, modify, and distribute this software for any
51 * purpose with or without fee is hereby granted, provided that the above
52 * copyright notice and this permission notice appear in all copies, and that
53 * the name of Digital Equipment Corporation not be used in advertising or
54 * publicity pertaining to distribution of the document or software without
55 * specific, written prior permission.
e62b2105 56 *
28f540f4
RM
57 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
58 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
59 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
60 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
61 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
62 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
63 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
64 * SOFTWARE.
b43b13ac
UD
65 */
66
67/*
68 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
69 *
70 * Permission to use, copy, modify, and distribute this software for any
71 * purpose with or without fee is hereby granted, provided that the above
72 * copyright notice and this permission notice appear in all copies.
73 *
74 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
75 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
76 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
77 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
78 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
79 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
80 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
81 * SOFTWARE.
28f540f4
RM
82 */
83
28f540f4
RM
84/*
85 * Send query to name server and wait for reply.
86 */
87
17a10319 88#include <assert.h>
df21c858 89#include <sys/types.h>
28f540f4
RM
90#include <sys/param.h>
91#include <sys/time.h>
92#include <sys/socket.h>
93#include <sys/uio.h>
e685e07d 94#include <sys/poll.h>
b43b13ac 95
28f540f4
RM
96#include <netinet/in.h>
97#include <arpa/nameser.h>
98#include <arpa/inet.h>
0420d888 99#include <sys/ioctl.h>
28f540f4 100
28f540f4 101#include <errno.h>
f433b06b 102#include <fcntl.h>
b43b13ac 103#include <netdb.h>
28f540f4 104#include <resolv.h>
b43b13ac
UD
105#include <signal.h>
106#include <stdio.h>
107#include <stdlib.h>
108#include <string.h>
109#include <unistd.h>
9744268c 110#include <kernel-features.h>
48e435cd 111#include <libc-internal.h>
b43b13ac 112
0420d888
UD
113#if PACKETSZ > 65536
114#define MAXPACKET PACKETSZ
115#else
116#define MAXPACKET 65536
117#endif
118
e685e07d 119/* From ev_streams.c. */
e62b2105 120
25337753
UD
121static inline void
122__attribute ((always_inline))
123evConsIovec(void *buf, size_t cnt, struct iovec *vec) {
124 memset(vec, 0xf5, sizeof (*vec));
125 vec->iov_base = buf;
126 vec->iov_len = cnt;
e685e07d 127}
28f540f4 128
e685e07d 129/* From ev_timers.c. */
30f9ca19 130
b43b13ac 131#define BILLION 1000000000
e685e07d 132
25337753
UD
133static inline void
134evConsTime(struct timespec *res, time_t sec, long nsec) {
135 res->tv_sec = sec;
136 res->tv_nsec = nsec;
b43b13ac 137}
28f540f4 138
25337753
UD
139static inline void
140evAddTime(struct timespec *res, const struct timespec *addend1,
141 const struct timespec *addend2) {
142 res->tv_sec = addend1->tv_sec + addend2->tv_sec;
143 res->tv_nsec = addend1->tv_nsec + addend2->tv_nsec;
144 if (res->tv_nsec >= BILLION) {
145 res->tv_sec++;
146 res->tv_nsec -= BILLION;
b43b13ac 147 }
b43b13ac
UD
148}
149
25337753
UD
150static inline void
151evSubTime(struct timespec *res, const struct timespec *minuend,
152 const struct timespec *subtrahend) {
153 res->tv_sec = minuend->tv_sec - subtrahend->tv_sec;
154 if (minuend->tv_nsec >= subtrahend->tv_nsec)
155 res->tv_nsec = minuend->tv_nsec - subtrahend->tv_nsec;
b43b13ac 156 else {
25337753
UD
157 res->tv_nsec = (BILLION
158 - subtrahend->tv_nsec + minuend->tv_nsec);
159 res->tv_sec--;
b43b13ac 160 }
b43b13ac
UD
161}
162
f1d70dad 163static int
b43b13ac
UD
164evCmpTime(struct timespec a, struct timespec b) {
165 long x = a.tv_sec - b.tv_sec;
166
167 if (x == 0L)
168 x = a.tv_nsec - b.tv_nsec;
169 return (x < 0L ? (-1) : x > 0L ? (1) : (0));
170}
171
f1d70dad 172static void
25337753 173evNowTime(struct timespec *res) {
b43b13ac
UD
174 struct timeval now;
175
176 if (gettimeofday(&now, NULL) < 0)
25337753
UD
177 evConsTime(res, 0, 0);
178 else
179 TIMEVAL_TO_TIMESPEC (&now, res);
b43b13ac 180}
b43b13ac 181
28f540f4 182
e685e07d
UD
183/* Options. Leave them on. */
184/* #undef DEBUG */
185#include "res_debug.h"
b43b13ac 186
e685e07d 187#define EXT(res) ((res)->_u._ext)
28f540f4 188
e685e07d
UD
189/* Forward. */
190
2212c142 191static struct sockaddr *get_nsaddr (res_state, int);
e685e07d 192static int send_vc(res_state, const u_char *, int,
1eb946b9
UD
193 const u_char *, int,
194 u_char **, int *, int *, int, u_char **,
ab09bf61 195 u_char **, int *, int *, int *);
e685e07d 196static int send_dg(res_state, const u_char *, int,
1eb946b9 197 const u_char *, int,
0420d888 198 u_char **, int *, int *, int,
1eb946b9 199 int *, int *, u_char **,
ab09bf61 200 u_char **, int *, int *, int *);
e685e07d
UD
201#ifdef DEBUG
202static void Aerror(const res_state, FILE *, const char *, int,
020a9a23 203 const struct sockaddr *);
e685e07d
UD
204static void Perror(const res_state, FILE *, const char *, int);
205#endif
438e8239 206static int sock_eq(struct sockaddr_in6 *, struct sockaddr_in6 *);
e685e07d 207
e685e07d
UD
208/* Public. */
209
28f540f4
RM
210/* int
211 * res_isourserver(ina)
212 * looks up "ina" in _res.ns_addr_list[]
213 * returns:
214 * 0 : not found
215 * >0 : found
216 * author:
217 * paul vixie, 29may94
218 */
219int
438e8239 220res_ourserver_p(const res_state statp, const struct sockaddr_in6 *inp)
438e8239 221{
b43b13ac 222 int ns;
28f540f4 223
3a85895f
PB
224 if (inp->sin6_family == AF_INET) {
225 struct sockaddr_in *in4p = (struct sockaddr_in *) inp;
e62b2105
UD
226 in_port_t port = in4p->sin_port;
227 in_addr_t addr = in4p->sin_addr.s_addr;
438e8239 228
2212c142 229 for (ns = 0; ns < statp->nscount; ns++) {
3a85895f 230 const struct sockaddr_in *srv =
2212c142 231 (struct sockaddr_in *) get_nsaddr (statp, ns);
438e8239 232
2212c142 233 if ((srv->sin_family == AF_INET) &&
3a85895f
PB
234 (srv->sin_port == port) &&
235 (srv->sin_addr.s_addr == INADDR_ANY ||
236 srv->sin_addr.s_addr == addr))
237 return (1);
238 }
239 } else if (inp->sin6_family == AF_INET6) {
2212c142
AS
240 for (ns = 0; ns < statp->nscount; ns++) {
241 const struct sockaddr_in6 *srv
242 = (struct sockaddr_in6 *) get_nsaddr (statp, ns);
243 if ((srv->sin6_family == AF_INET6) &&
3a85895f
PB
244 (srv->sin6_port == inp->sin6_port) &&
245 !(memcmp(&srv->sin6_addr, &in6addr_any,
246 sizeof (struct in6_addr)) &&
247 memcmp(&srv->sin6_addr, &inp->sin6_addr,
248 sizeof (struct in6_addr))))
249 return (1);
250 }
251 }
b43b13ac 252 return (0);
28f540f4
RM
253}
254
255/* int
256 * res_nameinquery(name, type, class, buf, eom)
257 * look for (name,type,class) in the query section of packet (buf,eom)
66715f83 258 * requires:
b43b13ac 259 * buf + HFIXEDSZ <= eom
28f540f4
RM
260 * returns:
261 * -1 : format error
262 * 0 : not found
263 * >0 : found
264 * author:
265 * paul vixie, 29may94
266 */
267int
b43b13ac
UD
268res_nameinquery(const char *name, int type, int class,
269 const u_char *buf, const u_char *eom)
28f540f4 270{
b43b13ac 271 const u_char *cp = buf + HFIXEDSZ;
28f540f4
RM
272 int qdcount = ntohs(((HEADER*)buf)->qdcount);
273
274 while (qdcount-- > 0) {
275 char tname[MAXDNAME+1];
b43b13ac 276 int n, ttype, tclass;
28f540f4
RM
277
278 n = dn_expand(buf, eom, cp, tname, sizeof tname);
279 if (n < 0)
280 return (-1);
281 cp += n;
66715f83
UD
282 if (cp + 2 * INT16SZ > eom)
283 return (-1);
697e1628
UD
284 NS_GET16(ttype, cp);
285 NS_GET16(tclass, cp);
b43b13ac
UD
286 if (ttype == type && tclass == class &&
287 ns_samename(tname, name) == 1)
28f540f4
RM
288 return (1);
289 }
290 return (0);
291}
6f9d8e68 292libresolv_hidden_def (res_nameinquery)
28f540f4
RM
293
294/* int
295 * res_queriesmatch(buf1, eom1, buf2, eom2)
296 * is there a 1:1 mapping of (name,type,class)
297 * in (buf1,eom1) and (buf2,eom2)?
298 * returns:
299 * -1 : format error
300 * 0 : not a 1:1 mapping
301 * >0 : is a 1:1 mapping
302 * author:
303 * paul vixie, 29may94
304 */
305int
b43b13ac
UD
306res_queriesmatch(const u_char *buf1, const u_char *eom1,
307 const u_char *buf2, const u_char *eom2)
28f540f4 308{
66715f83
UD
309 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
310 return (-1);
311
b43b13ac
UD
312 /*
313 * Only header section present in replies to
314 * dynamic update packets.
315 */
e685e07d
UD
316 if ((((HEADER *)buf1)->opcode == ns_o_update) &&
317 (((HEADER *)buf2)->opcode == ns_o_update))
b43b13ac
UD
318 return (1);
319
697e1628 320 /* Note that we initially do not convert QDCOUNT to the host byte
8e45b1ac 321 order. We can compare it with the second buffer's QDCOUNT
697e1628
UD
322 value without doing this. */
323 int qdcount = ((HEADER*)buf1)->qdcount;
324 if (qdcount != ((HEADER*)buf2)->qdcount)
28f540f4 325 return (0);
697e1628
UD
326
327 qdcount = htons (qdcount);
328 const u_char *cp = buf1 + HFIXEDSZ;
329
28f540f4
RM
330 while (qdcount-- > 0) {
331 char tname[MAXDNAME+1];
b43b13ac 332 int n, ttype, tclass;
28f540f4
RM
333
334 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
335 if (n < 0)
336 return (-1);
337 cp += n;
66715f83
UD
338 if (cp + 2 * INT16SZ > eom1)
339 return (-1);
697e1628
UD
340 NS_GET16(ttype, cp);
341 NS_GET16(tclass, cp);
28f540f4
RM
342 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
343 return (0);
344 }
345 return (1);
346}
6f9d8e68 347libresolv_hidden_def (res_queriesmatch)
28f540f4
RM
348
349int
0420d888 350__libc_res_nsend(res_state statp, const u_char *buf, int buflen,
1eb946b9
UD
351 const u_char *buf2, int buflen2,
352 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
ab09bf61 353 int *nansp2, int *resplen2, int *ansp2_malloced)
28f540f4 354{
b7da31a1 355 int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
28f540f4 356
e685e07d
UD
357 if (statp->nscount == 0) {
358 __set_errno (ESRCH);
359 return (-1);
360 }
0420d888 361
1eb946b9 362 if (anssiz < (buf2 == NULL ? 1 : 2) * HFIXEDSZ) {
66715f83
UD
363 __set_errno (EINVAL);
364 return (-1);
365 }
0420d888 366
b43b13ac 367 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
3d61b63c 368 (stdout, ";; res_send()\n"), buf, buflen);
1eb946b9
UD
369 v_circuit = ((statp->options & RES_USEVC)
370 || buflen > PACKETSZ
371 || buflen2 > PACKETSZ);
28f540f4 372 gotsomewhere = 0;
28f540f4 373 terrno = ETIMEDOUT;
28f540f4 374
b43b13ac 375 /*
e685e07d
UD
376 * If the ns_addr_list in the resolver context has changed, then
377 * invalidate our cached copy and the associated timing data.
b43b13ac 378 */
2212c142 379 if (EXT(statp).nscount != 0) {
e685e07d
UD
380 int needclose = 0;
381
382 if (EXT(statp).nscount != statp->nscount)
383 needclose++;
384 else
2212c142
AS
385 for (ns = 0; ns < statp->nscount; ns++) {
386 if (statp->nsaddr_list[ns].sin_family != 0
b64e1566 387 && !sock_eq((struct sockaddr_in6 *)
2212c142 388 &statp->nsaddr_list[ns],
b64e1566 389 EXT(statp).nsaddrs[ns]))
438e8239 390 {
e685e07d
UD
391 needclose++;
392 break;
393 }
b64e1566 394 }
2212c142 395 if (needclose) {
cb07f6f6 396 __res_iclose(statp, false);
2212c142
AS
397 EXT(statp).nscount = 0;
398 }
e685e07d
UD
399 }
400
401 /*
402 * Maybe initialize our private copy of the ns_addr_list.
403 */
2212c142
AS
404 if (EXT(statp).nscount == 0) {
405 for (ns = 0; ns < statp->nscount; ns++) {
406 EXT(statp).nssocks[ns] = -1;
407 if (statp->nsaddr_list[ns].sin_family == 0)
408 continue;
409 if (EXT(statp).nsaddrs[ns] == NULL)
410 EXT(statp).nsaddrs[ns] =
438e8239 411 malloc(sizeof (struct sockaddr_in6));
2212c142
AS
412 if (EXT(statp).nsaddrs[ns] != NULL)
413 memset (mempcpy(EXT(statp).nsaddrs[ns],
cabba934 414 &statp->nsaddr_list[ns],
0f8f993c
UD
415 sizeof (struct sockaddr_in)),
416 '\0',
417 sizeof (struct sockaddr_in6)
418 - sizeof (struct sockaddr_in));
b64e1566 419 }
2212c142 420 EXT(statp).nscount = statp->nscount;
e685e07d
UD
421 }
422
423 /*
424 * Some resolvers want to even out the load on their nameservers.
425 * Note that RES_BLAST overrides RES_ROTATE.
426 */
bbe989ee 427 if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0)) {
2212c142
AS
428 struct sockaddr_in ina;
429 struct sockaddr_in6 *inp;
430 int lastns = statp->nscount - 1;
431 int fd;
432
433 inp = EXT(statp).nsaddrs[0];
434 ina = statp->nsaddr_list[0];
435 fd = EXT(statp).nssocks[0];
436 for (ns = 0; ns < lastns; ns++) {
437 EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
438 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
439 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
b64e1566 440 }
2212c142
AS
441 EXT(statp).nsaddrs[lastns] = inp;
442 statp->nsaddr_list[lastns] = ina;
443 EXT(statp).nssocks[lastns] = fd;
b43b13ac 444 }
30f9ca19 445
28f540f4 446 /*
e685e07d 447 * Send request, RETRY times, or until successful.
28f540f4 448 */
b43b13ac 449 for (try = 0; try < statp->retry; try++) {
2212c142 450 for (ns = 0; ns < statp->nscount; ns++)
438e8239 451 {
a092b645
YD
452#ifdef DEBUG
453 char tmpbuf[40];
2212c142
AS
454 struct sockaddr *nsap = get_nsaddr (statp, ns);
455#endif
438e8239 456
1eb946b9 457 same_ns:
020a9a23
UD
458 Dprint(statp->options & RES_DEBUG,
459 (stdout, ";; Querying server (# %d) address = %s\n",
2212c142
AS
460 ns + 1, inet_ntop(nsap->sa_family,
461 (nsap->sa_family == AF_INET6
f2b3078e
MS
462 ? (void *) &((struct sockaddr_in6 *) nsap)->sin6_addr
463 : (void *) &((struct sockaddr_in *) nsap)->sin_addr),
020a9a23 464 tmpbuf, sizeof (tmpbuf))));
28f540f4 465
a1ffb40e 466 if (__glibc_unlikely (v_circuit)) {
b43b13ac
UD
467 /* Use VC; at most one attempt per server. */
468 try = statp->retry;
1eb946b9
UD
469 n = send_vc(statp, buf, buflen, buf2, buflen2,
470 &ans, &anssiz, &terrno,
ab09bf61
AS
471 ns, ansp, ansp2, nansp2, resplen2,
472 ansp2_malloced);
e685e07d
UD
473 if (n < 0)
474 return (-1);
57912a71 475 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
28f540f4 476 goto next_ns;
28f540f4 477 } else {
e685e07d 478 /* Use datagrams. */
1eb946b9
UD
479 n = send_dg(statp, buf, buflen, buf2, buflen2,
480 &ans, &anssiz, &terrno,
481 ns, &v_circuit, &gotsomewhere, ansp,
ab09bf61 482 ansp2, nansp2, resplen2, ansp2_malloced);
e685e07d
UD
483 if (n < 0)
484 return (-1);
57912a71 485 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
b43b13ac 486 goto next_ns;
e685e07d 487 if (v_circuit)
1eb946b9 488 // XXX Check whether both requests failed or
b7da31a1 489 // XXX whether one has been answered successfully
28f540f4 490 goto same_ns;
e685e07d
UD
491 }
492
1eb946b9
UD
493 resplen = n;
494
b43b13ac
UD
495 Dprint((statp->options & RES_DEBUG) ||
496 ((statp->pfcode & RES_PRF_REPLY) &&
497 (statp->pfcode & RES_PRF_HEAD1)),
a4219bc4 498 (stdout, ";; got answer:\n"));
e685e07d 499
b43b13ac
UD
500 DprintQ((statp->options & RES_DEBUG) ||
501 (statp->pfcode & RES_PRF_REPLY),
020a9a23 502 (stdout, "%s", ""),
e685e07d 503 ans, (resplen > anssiz) ? anssiz : resplen);
a092b645 504 if (buf2 != NULL) {
1eb946b9
UD
505 DprintQ((statp->options & RES_DEBUG) ||
506 (statp->pfcode & RES_PRF_REPLY),
507 (stdout, "%s", ""),
b7da31a1 508 *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
a092b645 509 }
e685e07d 510
28f540f4 511 /*
28f540f4
RM
512 * If we have temporarily opened a virtual circuit,
513 * or if we haven't been asked to keep a socket open,
514 * close the socket.
515 */
e685e07d
UD
516 if ((v_circuit && (statp->options & RES_USEVC) == 0) ||
517 (statp->options & RES_STAYOPEN) == 0) {
cb07f6f6 518 __res_iclose(statp, false);
28f540f4 519 }
b43b13ac
UD
520 return (resplen);
521 next_ns: ;
28f540f4
RM
522 } /*foreach ns*/
523 } /*foreach retry*/
cb07f6f6 524 __res_iclose(statp, false);
7ef90c15 525 if (!v_circuit) {
28f540f4 526 if (!gotsomewhere)
b43b13ac 527 __set_errno (ECONNREFUSED); /* no nameservers found */
28f540f4 528 else
b43b13ac 529 __set_errno (ETIMEDOUT); /* no answer obtained */
7ef90c15 530 } else
c4029823 531 __set_errno (terrno);
b43b13ac 532 return (-1);
28f540f4
RM
533}
534
0420d888
UD
535int
536res_nsend(res_state statp,
537 const u_char *buf, int buflen, u_char *ans, int anssiz)
538{
1eb946b9 539 return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
ab09bf61 540 NULL, NULL, NULL, NULL, NULL);
0420d888 541}
6f9d8e68 542libresolv_hidden_def (res_nsend)
0420d888 543
e685e07d
UD
544/* Private */
545
2212c142
AS
546static struct sockaddr *
547get_nsaddr (res_state statp, int n)
548{
549
550 if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
551 /* EXT(statp).nsaddrs[n] holds an address that is larger than
552 struct sockaddr, and user code did not update
553 statp->nsaddr_list[n]. */
554 return (struct sockaddr *) EXT(statp).nsaddrs[n];
555 else
556 /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
557 has the same content as EXT(statp).nsaddrs[n]. */
558 return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
559}
560
b66d837b
FW
561/* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
562 is not NULL, and return zero. */
563static int
564__attribute__ ((warn_unused_result))
565close_and_return_error (res_state statp, int *resplen2)
566{
567 __res_iclose(statp, false);
568 if (resplen2 != NULL)
569 *resplen2 = 0;
570 return 0;
571}
572
e9db92d3
CD
573/* The send_vc function is responsible for sending a DNS query over TCP
574 to the nameserver numbered NS from the res_state STATP i.e.
575 EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
576 IPv6 queries at the same serially on the same socket.
577
578 Please note that for TCP there is no way to disable sending both
579 queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
580 and sends the queries serially and waits for the result after each
12f1ae05 581 sent query. This implementation should be corrected to honour these
e9db92d3
CD
582 options.
583
584 Please also note that for TCP we send both queries over the same
585 socket one after another. This technically violates best practice
586 since the server is allowed to read the first query, respond, and
587 then close the socket (to service another client). If the server
588 does this, then the remaining second query in the socket data buffer
589 will cause the server to send the client an RST which will arrive
590 asynchronously and the client's OS will likely tear down the socket
591 receive buffer resulting in a potentially short read and lost
592 response data. This will force the client to retry the query again,
593 and this process may repeat until all servers and connection resets
594 are exhausted and then the query will fail. It's not known if this
595 happens with any frequency in real DNS server implementations. This
596 implementation should be corrected to use two sockets by default for
597 parallel queries.
598
599 The query stored in BUF of BUFLEN length is sent first followed by
600 the query stored in BUF2 of BUFLEN2 length. Queries are sent
601 serially on the same socket.
602
603 Answers to the query are stored firstly in *ANSP up to a max of
604 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
605 is non-NULL (to indicate that modifying the answer buffer is allowed)
606 then malloc is used to allocate a new response buffer and ANSCP and
607 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
608 are needed but ANSCP is NULL, then as much of the response as
609 possible is read into the buffer, but the results will be truncated.
610 When truncation happens because of a small answer buffer the DNS
611 packets header field TC will bet set to 1, indicating a truncated
612 message and the rest of the socket data will be read and discarded.
613
614 Answers to the query are stored secondly in *ANSP2 up to a max of
615 *ANSSIZP2 bytes, with the actual response length stored in
616 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
617 is non-NULL (required for a second query) then malloc is used to
618 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
619 size and *ANSP2_MALLOCED is set to 1.
620
621 The ANSP2_MALLOCED argument will eventually be removed as the
622 change in buffer pointer can be used to detect the buffer has
623 changed and that the caller should use free on the new buffer.
624
625 Note that the answers may arrive in any order from the server and
626 therefore the first and second answer buffers may not correspond to
627 the first and second queries.
628
629 It is not supported to call this function with a non-NULL ANSP2
630 but a NULL ANSCP. Put another way, you can call send_vc with a
631 single unmodifiable buffer or two modifiable buffers, but no other
632 combination is supported.
633
634 It is the caller's responsibility to free the malloc allocated
635 buffers by detecting that the pointers have changed from their
636 original values i.e. *ANSCP or *ANSP2 has changed.
637
638 If errors are encountered then *TERRNO is set to an appropriate
639 errno value and a zero result is returned for a recoverable error,
640 and a less-than zero result is returned for a non-recoverable error.
641
642 If no errors are encountered then *TERRNO is left unmodified and
643 a the length of the first response in bytes is returned. */
e685e07d
UD
644static int
645send_vc(res_state statp,
1eb946b9
UD
646 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
647 u_char **ansp, int *anssizp,
648 int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
ab09bf61 649 int *resplen2, int *ansp2_malloced)
e685e07d
UD
650{
651 const HEADER *hp = (HEADER *) buf;
1eb946b9 652 const HEADER *hp2 = (HEADER *) buf2;
e9db92d3 653 HEADER *anhp = (HEADER *) *ansp;
2212c142 654 struct sockaddr *nsap = get_nsaddr (statp, ns);
48e435cd
SL
655 int truncating, connreset, n;
656 /* On some architectures compiler might emit a warning indicating
657 'resplen' may be used uninitialized. However if buf2 == NULL
658 then this code won't be executed; if buf2 != NULL, then first
659 time round the loop recvresp1 and recvresp2 will be 0 so this
660 code won't be executed but "thisresplenp = &resplen;" followed
661 by "*thisresplenp = rlen;" will be executed so that subsequent
662 times round the loop resplen has been initialized. So this is
663 a false-positive.
664 */
48e435cd 665 DIAG_PUSH_NEEDS_COMMENT;
0cb9dcc8 666 DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
48e435cd 667 int resplen;
48e435cd 668 DIAG_POP_NEEDS_COMMENT;
1eb946b9 669 struct iovec iov[4];
e685e07d 670 u_short len;
1eb946b9 671 u_short len2;
e685e07d
UD
672 u_char *cp;
673
674 connreset = 0;
675 same_ns:
676 truncating = 0;
677
678 /* Are we still talking to whom we want to talk to? */
679 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
438e8239 680 struct sockaddr_in6 peer;
9cfe5381 681 socklen_t size = sizeof peer;
e685e07d
UD
682
683 if (getpeername(statp->_vcsock,
684 (struct sockaddr *)&peer, &size) < 0 ||
2212c142
AS
685 !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
686 __res_iclose(statp, false);
e685e07d
UD
687 statp->_flags &= ~RES_F_VC;
688 }
689 }
690
691 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
692 if (statp->_vcsock >= 0)
cb07f6f6 693 __res_iclose(statp, false);
e685e07d 694
2212c142 695 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
e685e07d
UD
696 if (statp->_vcsock < 0) {
697 *terrno = errno;
698 Perror(statp, stderr, "socket(vc)", errno);
b9bdfa7c
FW
699 if (resplen2 != NULL)
700 *resplen2 = 0;
e685e07d
UD
701 return (-1);
702 }
703 __set_errno (0);
2212c142
AS
704 if (connect(statp->_vcsock, nsap,
705 nsap->sa_family == AF_INET
9fc42dfd
UD
706 ? sizeof (struct sockaddr_in)
707 : sizeof (struct sockaddr_in6)) < 0) {
e685e07d 708 *terrno = errno;
2212c142 709 Aerror(statp, stderr, "connect/vc", errno, nsap);
b9bdfa7c 710 return close_and_return_error (statp, resplen2);
e685e07d
UD
711 }
712 statp->_flags |= RES_F_VC;
28f540f4 713 }
e685e07d
UD
714
715 /*
716 * Send length & message
717 */
1eb946b9 718 len = htons ((u_short) buflen);
25337753
UD
719 evConsIovec(&len, INT16SZ, &iov[0]);
720 evConsIovec((void*)buf, buflen, &iov[1]);
1eb946b9
UD
721 int niov = 2;
722 ssize_t explen = INT16SZ + buflen;
723 if (buf2 != NULL) {
724 len2 = htons ((u_short) buflen2);
725 evConsIovec(&len2, INT16SZ, &iov[2]);
726 evConsIovec((void*)buf2, buflen2, &iov[3]);
727 niov = 4;
728 explen += INT16SZ + buflen2;
729 }
730 if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) {
e685e07d
UD
731 *terrno = errno;
732 Perror(statp, stderr, "write failed", errno);
b9bdfa7c 733 return close_and_return_error (statp, resplen2);
e685e07d
UD
734 }
735 /*
736 * Receive length & response
737 */
1eb946b9 738 int recvresp1 = 0;
e9db92d3
CD
739 /* Skip the second response if there is no second query.
740 To do that we mark the second response as received. */
1eb946b9 741 int recvresp2 = buf2 == NULL;
b7da31a1 742 uint16_t rlen16;
e39e6946
UD
743 read_len:
744 cp = (u_char *)&rlen16;
b7da31a1 745 len = sizeof(rlen16);
e39e6946 746 while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, cp,
25337753 747 (int)len))) > 0) {
e685e07d
UD
748 cp += n;
749 if ((len -= n) <= 0)
750 break;
751 }
752 if (n <= 0) {
753 *terrno = errno;
754 Perror(statp, stderr, "read failed", errno);
e685e07d
UD
755 /*
756 * A long running process might get its TCP
757 * connection reset if the remote server was
758 * restarted. Requery the server instead of
759 * trying a new one. When there is only one
760 * server, this means that a query might work
761 * instead of failing. We only allow one reset
762 * per query to prevent looping.
763 */
b9bdfa7c
FW
764 if (*terrno == ECONNRESET && !connreset)
765 {
766 __res_iclose (statp, false);
767 connreset = 1;
768 goto same_ns;
769 }
770 return close_and_return_error (statp, resplen2);
e685e07d 771 }
b7da31a1 772 int rlen = ntohs (rlen16);
1eb946b9
UD
773
774 int *thisanssizp;
775 u_char **thisansp;
776 int *thisresplenp;
777 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
e9db92d3
CD
778 /* We have not received any responses
779 yet or we only have one response to
780 receive. */
1eb946b9
UD
781 thisanssizp = anssizp;
782 thisansp = anscp ?: ansp;
783 assert (anscp != NULL || ansp2 == NULL);
784 thisresplenp = &resplen;
785 } else {
1eb946b9
UD
786 thisanssizp = anssizp2;
787 thisansp = ansp2;
788 thisresplenp = resplen2;
789 }
790 anhp = (HEADER *) *thisansp;
791
b7da31a1 792 *thisresplenp = rlen;
e9db92d3
CD
793 /* Is the answer buffer too small? */
794 if (*thisanssizp < rlen) {
795 /* If the current buffer is not the the static
796 user-supplied buffer then we can reallocate
797 it. */
798 if (thisansp != NULL && thisansp != ansp) {
799 /* Always allocate MAXPACKET, callers expect
800 this specific size. */
1eb946b9 801 u_char *newp = malloc (MAXPACKET);
b9bdfa7c
FW
802 if (newp == NULL)
803 {
804 *terrno = ENOMEM;
805 return close_and_return_error (statp, resplen2);
806 }
1eb946b9
UD
807 *thisanssizp = MAXPACKET;
808 *thisansp = newp;
ab09bf61
AS
809 if (thisansp == ansp2)
810 *ansp2_malloced = 1;
1eb946b9 811 anhp = (HEADER *) newp;
e9db92d3
CD
812 /* A uint16_t can't be larger than MAXPACKET
813 thus it's safe to allocate MAXPACKET but
814 read RLEN bytes instead. */
b7da31a1 815 len = rlen;
0420d888
UD
816 } else {
817 Dprint(statp->options & RES_DEBUG,
818 (stdout, ";; response truncated\n")
819 );
820 truncating = 1;
1eb946b9 821 len = *thisanssizp;
0420d888 822 }
e685e07d 823 } else
b7da31a1 824 len = rlen;
1eb946b9 825
a1ffb40e 826 if (__glibc_unlikely (len < HFIXEDSZ)) {
e685e07d
UD
827 /*
828 * Undersized message.
829 */
830 Dprint(statp->options & RES_DEBUG,
831 (stdout, ";; undersized: %d\n", len));
832 *terrno = EMSGSIZE;
b9bdfa7c 833 return close_and_return_error (statp, resplen2);
e685e07d 834 }
1eb946b9
UD
835
836 cp = *thisansp;
e685e07d
UD
837 while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
838 cp += n;
839 len -= n;
840 }
a1ffb40e 841 if (__glibc_unlikely (n <= 0)) {
e685e07d
UD
842 *terrno = errno;
843 Perror(statp, stderr, "read(vc)", errno);
b9bdfa7c 844 return close_and_return_error (statp, resplen2);
e685e07d 845 }
a1ffb40e 846 if (__glibc_unlikely (truncating)) {
e685e07d
UD
847 /*
848 * Flush rest of answer so connection stays in synch.
849 */
850 anhp->tc = 1;
b7da31a1 851 len = rlen - *thisanssizp;
e685e07d
UD
852 while (len != 0) {
853 char junk[PACKETSZ];
854
855 n = read(statp->_vcsock, junk,
856 (len > sizeof junk) ? sizeof junk : len);
857 if (n > 0)
858 len -= n;
859 else
860 break;
861 }
862 }
863 /*
c0c3f78a 864 * If the calling application has bailed out of
e685e07d
UD
865 * a previous call and failed to arrange to have
866 * the circuit closed or the server has got
867 * itself confused, then drop the packet and
868 * wait for the correct one.
869 */
1eb946b9
UD
870 if ((recvresp1 || hp->id != anhp->id)
871 && (recvresp2 || hp2->id != anhp->id)) {
e685e07d
UD
872 DprintQ((statp->options & RES_DEBUG) ||
873 (statp->pfcode & RES_PRF_REPLY),
874 (stdout, ";; old answer (unexpected):\n"),
1eb946b9 875 *thisansp,
a092b645 876 (rlen > *thisanssizp) ? *thisanssizp: rlen);
e685e07d
UD
877 goto read_len;
878 }
879
1eb946b9
UD
880 /* Mark which reply we received. */
881 if (recvresp1 == 0 && hp->id == anhp->id)
882 recvresp1 = 1;
883 else
884 recvresp2 = 1;
885 /* Repeat waiting if we have a second answer to arrive. */
886 if ((recvresp1 & recvresp2) == 0)
887 goto read_len;
888
e685e07d
UD
889 /*
890 * All is well, or the error is fatal. Signal that the
891 * next nameserver ought not be tried.
892 */
b7da31a1 893 return resplen;
28f540f4 894}
845dcb57 895
b43b13ac 896static int
44d20bca 897reopen (res_state statp, int *terrno, int ns)
e685e07d 898{
e685e07d 899 if (EXT(statp).nssocks[ns] == -1) {
2212c142 900 struct sockaddr *nsap = get_nsaddr (statp, ns);
ace4e23f 901 socklen_t slen;
44d20bca 902
438e8239 903 /* only try IPv6 if IPv6 NS and if not failed before */
ace4e23f 904 if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
52fb79d6
FW
905 EXT(statp).nssocks[ns]
906 = socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, 0);
ae1ad3ae
UD
907 if (EXT(statp).nssocks[ns] < 0)
908 statp->ipv6_unavail = errno == EAFNOSUPPORT;
ace4e23f
UD
909 slen = sizeof (struct sockaddr_in6);
910 } else if (nsap->sa_family == AF_INET) {
52fb79d6
FW
911 EXT(statp).nssocks[ns]
912 = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);
ace4e23f 913 slen = sizeof (struct sockaddr_in);
9744268c 914 }
e685e07d
UD
915 if (EXT(statp).nssocks[ns] < 0) {
916 *terrno = errno;
917 Perror(statp, stderr, "socket(dg)", errno);
918 return (-1);
919 }
ae1ad3ae 920
e685e07d
UD
921 /*
922 * On a 4.3BSD+ machine (client and server,
923 * actually), sending to a nameserver datagram
924 * port with no nameserver will cause an
925 * ICMP port unreachable message to be returned.
926 * If our datagram socket is "connected" to the
927 * server, we get an ECONNREFUSED error on the next
928 * socket operation, and select returns if the
929 * error message is received. We can thus detect
930 * the absence of a nameserver without timing out.
931 */
93fe09cb
CD
932 /* With GCC 5.3 when compiling with -Os the compiler
933 emits a warning that slen may be used uninitialized,
934 but that is never true. Both slen and
935 EXT(statp).nssocks[ns] are initialized together or
936 the function return -1 before control flow reaches
937 the call to connect with slen. */
938 DIAG_PUSH_NEEDS_COMMENT;
0cb9dcc8 939 DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
ace4e23f 940 if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
93fe09cb 941 DIAG_POP_NEEDS_COMMENT;
ace4e23f 942 Aerror(statp, stderr, "connect(dg)", errno, nsap);
cb07f6f6 943 __res_iclose(statp, false);
e685e07d
UD
944 return (0);
945 }
e685e07d 946 }
17a10319 947
44d20bca
UD
948 return 1;
949}
950
e9db92d3
CD
951/* The send_dg function is responsible for sending a DNS query over UDP
952 to the nameserver numbered NS from the res_state STATP i.e.
953 EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
954 along with the ability to send the query in parallel for both stacks
955 (default) or serially (RES_SINGLKUP). It also supports serial lookup
956 with a close and reopen of the socket used to talk to the server
957 (RES_SNGLKUPREOP) to work around broken name servers.
958
959 The query stored in BUF of BUFLEN length is sent first followed by
960 the query stored in BUF2 of BUFLEN2 length. Queries are sent
961 in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
962
963 Answers to the query are stored firstly in *ANSP up to a max of
964 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
965 is non-NULL (to indicate that modifying the answer buffer is allowed)
966 then malloc is used to allocate a new response buffer and ANSCP and
967 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
968 are needed but ANSCP is NULL, then as much of the response as
969 possible is read into the buffer, but the results will be truncated.
970 When truncation happens because of a small answer buffer the DNS
971 packets header field TC will bet set to 1, indicating a truncated
972 message, while the rest of the UDP packet is discarded.
973
974 Answers to the query are stored secondly in *ANSP2 up to a max of
975 *ANSSIZP2 bytes, with the actual response length stored in
976 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
977 is non-NULL (required for a second query) then malloc is used to
978 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
979 size and *ANSP2_MALLOCED is set to 1.
980
981 The ANSP2_MALLOCED argument will eventually be removed as the
982 change in buffer pointer can be used to detect the buffer has
983 changed and that the caller should use free on the new buffer.
984
985 Note that the answers may arrive in any order from the server and
986 therefore the first and second answer buffers may not correspond to
987 the first and second queries.
988
989 It is not supported to call this function with a non-NULL ANSP2
990 but a NULL ANSCP. Put another way, you can call send_vc with a
991 single unmodifiable buffer or two modifiable buffers, but no other
992 combination is supported.
993
994 It is the caller's responsibility to free the malloc allocated
995 buffers by detecting that the pointers have changed from their
996 original values i.e. *ANSCP or *ANSP2 has changed.
997
998 If an answer is truncated because of UDP datagram DNS limits then
999 *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
1000 the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
1001 if any progress was made reading a response from the nameserver and
1002 is used by the caller to distinguish between ECONNREFUSED and
1003 ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
1004
1005 If errors are encountered then *TERRNO is set to an appropriate
1006 errno value and a zero result is returned for a recoverable error,
1007 and a less-than zero result is returned for a non-recoverable error.
1008
1009 If no errors are encountered then *TERRNO is left unmodified and
1010 a the length of the first response in bytes is returned. */
44d20bca
UD
1011static int
1012send_dg(res_state statp,
1013 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
1014 u_char **ansp, int *anssizp,
1015 int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
ab09bf61 1016 u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
44d20bca
UD
1017{
1018 const HEADER *hp = (HEADER *) buf;
1019 const HEADER *hp2 = (HEADER *) buf2;
44d20bca
UD
1020 struct timespec now, timeout, finish;
1021 struct pollfd pfd[1];
3a85895f 1022 int ptimeout;
44d20bca 1023 struct sockaddr_in6 from;
75ded9bc
UD
1024 int resplen = 0;
1025 int n;
44d20bca 1026
f433b06b
UD
1027 /*
1028 * Compute time for the total operation.
1029 */
ae061910 1030 int seconds = (statp->retrans << ns);
f433b06b
UD
1031 if (ns > 0)
1032 seconds /= statp->nscount;
1033 if (seconds <= 0)
1034 seconds = 1;
44d20bca 1035 bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
c030f70c
UD
1036 bool single_request = (((statp->options & RES_SNGLKUP) != 0)
1037 | single_request_reopen);
ae061910 1038 int save_gotsomewhere = *gotsomewhere;
44d20bca
UD
1039
1040 int retval;
1041 retry_reopen:
1042 retval = reopen (statp, terrno, ns);
1043 if (retval <= 0)
b66d837b
FW
1044 {
1045 if (resplen2 != NULL)
1046 *resplen2 = 0;
1047 return retval;
1048 }
ae061910 1049 retry:
f433b06b
UD
1050 evNowTime(&now);
1051 evConsTime(&timeout, seconds, 0);
1052 evAddTime(&finish, &now, &timeout);
1053 int need_recompute = 0;
17a10319 1054 int nwritten = 0;
1eb946b9 1055 int recvresp1 = 0;
e9db92d3
CD
1056 /* Skip the second response if there is no second query.
1057 To do that we mark the second response as received. */
1eb946b9 1058 int recvresp2 = buf2 == NULL;
17a10319
UD
1059 pfd[0].fd = EXT(statp).nssocks[ns];
1060 pfd[0].events = POLLOUT;
1061 wait:
1062 if (need_recompute) {
8e45b1ac 1063 recompute_resend:
17a10319
UD
1064 evNowTime(&now);
1065 if (evCmpTime(finish, now) <= 0) {
8e45b1ac
UD
1066 poll_err_out:
1067 Perror(statp, stderr, "poll", errno);
b66d837b 1068 return close_and_return_error (statp, resplen2);
17a10319
UD
1069 }
1070 evSubTime(&timeout, &finish, &now);
ae061910 1071 need_recompute = 0;
17a10319 1072 }
3a85895f 1073 /* Convert struct timespec in milliseconds. */
f433b06b
UD
1074 ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
1075
17a10319
UD
1076 n = 0;
1077 if (nwritten == 0)
1078 n = __poll (pfd, 1, 0);
a1ffb40e 1079 if (__glibc_unlikely (n == 0)) {
f433b06b
UD
1080 n = __poll (pfd, 1, ptimeout);
1081 need_recompute = 1;
1082 }
f433b06b 1083 if (n == 0) {
e2003883 1084 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
74b3cf22 1085 if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
e2003883 1086 {
ae061910
UD
1087 /* There are quite a few broken name servers out
1088 there which don't handle two outstanding
1089 requests from the same source. There are also
1090 broken firewall settings. If we time out after
1091 having received one answer switch to the mode
1092 where we send the second request only once we
1093 have received the first answer. */
74b3cf22
UD
1094 if (!single_request)
1095 {
310647e9 1096 statp->options |= RES_SNGLKUP;
74b3cf22
UD
1097 single_request = true;
1098 *gotsomewhere = save_gotsomewhere;
1099 goto retry;
1100 }
44d20bca
UD
1101 else if (!single_request_reopen)
1102 {
1103 statp->options |= RES_SNGLKUPREOP;
1104 single_request_reopen = true;
1105 *gotsomewhere = save_gotsomewhere;
1106 __res_iclose (statp, false);
1107 goto retry_reopen;
1108 }
74b3cf22
UD
1109
1110 *resplen2 = 1;
1111 return resplen;
e2003883 1112 }
5908f779 1113
f433b06b 1114 *gotsomewhere = 1;
b66d837b
FW
1115 if (resplen2 != NULL)
1116 *resplen2 = 0;
1117 return 0;
f433b06b
UD
1118 }
1119 if (n < 0) {
8e45b1ac
UD
1120 if (errno == EINTR)
1121 goto recompute_resend;
1122
1123 goto poll_err_out;
f433b06b
UD
1124 }
1125 __set_errno (0);
17a10319 1126 if (pfd[0].revents & POLLOUT) {
c030f70c
UD
1127#ifndef __ASSUME_SENDMMSG
1128 static int have_sendmmsg;
1129#else
1130# define have_sendmmsg 1
1131#endif
1132 if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
1133 && !single_request)
1134 {
1135 struct iovec iov[2];
1136 struct mmsghdr reqs[2];
1137 reqs[0].msg_hdr.msg_name = NULL;
1138 reqs[0].msg_hdr.msg_namelen = 0;
1139 reqs[0].msg_hdr.msg_iov = &iov[0];
1140 reqs[0].msg_hdr.msg_iovlen = 1;
1141 iov[0].iov_base = (void *) buf;
1142 iov[0].iov_len = buflen;
1143 reqs[0].msg_hdr.msg_control = NULL;
1144 reqs[0].msg_hdr.msg_controllen = 0;
1145
1146 reqs[1].msg_hdr.msg_name = NULL;
1147 reqs[1].msg_hdr.msg_namelen = 0;
1148 reqs[1].msg_hdr.msg_iov = &iov[1];
1149 reqs[1].msg_hdr.msg_iovlen = 1;
1150 iov[1].iov_base = (void *) buf2;
1151 iov[1].iov_len = buflen2;
1152 reqs[1].msg_hdr.msg_control = NULL;
1153 reqs[1].msg_hdr.msg_controllen = 0;
1154
123be9de 1155 int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
a1ffb40e 1156 if (__glibc_likely (ndg == 2))
c030f70c 1157 {
966977f1
UD
1158 if (reqs[0].msg_len != buflen
1159 || reqs[1].msg_len != buflen2)
1160 goto fail_sendmmsg;
1eb946b9 1161
c030f70c
UD
1162 pfd[0].events = POLLIN;
1163 nwritten += 2;
1164 }
1165 else if (ndg == 1 && reqs[0].msg_len == buflen)
1166 goto just_one;
966977f1 1167 else if (ndg < 0 && (errno == EINTR || errno == EAGAIN))
c030f70c
UD
1168 goto recompute_resend;
1169 else
1170 {
1171#ifndef __ASSUME_SENDMMSG
a1ffb40e 1172 if (__glibc_unlikely (have_sendmmsg == 0))
c030f70c 1173 {
966977f1 1174 if (ndg < 0 && errno == ENOSYS)
c030f70c
UD
1175 {
1176 have_sendmmsg = -1;
1177 goto try_send;
1178 }
1179 have_sendmmsg = 1;
1180 }
1181#endif
1182
966977f1 1183 fail_sendmmsg:
c030f70c 1184 Perror(statp, stderr, "sendmmsg", errno);
b66d837b 1185 return close_and_return_error (statp, resplen2);
c030f70c
UD
1186 }
1187 }
1eb946b9 1188 else
c030f70c
UD
1189 {
1190 ssize_t sr;
1191#ifndef __ASSUME_SENDMMSG
1192 try_send:
1193#endif
1194 if (nwritten != 0)
1195 sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
1196 else
1197 sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
1198
8e6d1083 1199 if (sr != (nwritten != 0 ? buflen2 : buflen)) {
c030f70c
UD
1200 if (errno == EINTR || errno == EAGAIN)
1201 goto recompute_resend;
1202 Perror(statp, stderr, "send", errno);
b66d837b 1203 return close_and_return_error (statp, resplen2);
c030f70c
UD
1204 }
1205 just_one:
1206 if (nwritten != 0 || buf2 == NULL || single_request)
1207 pfd[0].events = POLLIN;
1208 else
1209 pfd[0].events = POLLIN | POLLOUT;
1210 ++nwritten;
1211 }
17a10319 1212 goto wait;
8aeb5058 1213 } else if (pfd[0].revents & POLLIN) {
1eb946b9
UD
1214 int *thisanssizp;
1215 u_char **thisansp;
1216 int *thisresplenp;
1217
1218 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
e9db92d3
CD
1219 /* We have not received any responses
1220 yet or we only have one response to
1221 receive. */
1eb946b9
UD
1222 thisanssizp = anssizp;
1223 thisansp = anscp ?: ansp;
1224 assert (anscp != NULL || ansp2 == NULL);
1225 thisresplenp = &resplen;
1226 } else {
1eb946b9
UD
1227 thisanssizp = anssizp2;
1228 thisansp = ansp2;
1229 thisresplenp = resplen2;
1230 }
1231
1232 if (*thisanssizp < MAXPACKET
e9db92d3
CD
1233 /* If the current buffer is not the the static
1234 user-supplied buffer then we can reallocate
1235 it. */
1236 && (thisansp != NULL && thisansp != ansp)
c4e42566 1237#ifdef FIONREAD
e9db92d3 1238 /* Is the size too small? */
1eb946b9 1239 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
c4e42566
RM
1240 || *thisanssizp < *thisresplenp)
1241#endif
1242 ) {
e9db92d3
CD
1243 /* Always allocate MAXPACKET, callers expect
1244 this specific size. */
1eb946b9
UD
1245 u_char *newp = malloc (MAXPACKET);
1246 if (newp != NULL) {
e9db92d3
CD
1247 *thisanssizp = MAXPACKET;
1248 *thisansp = newp;
ab09bf61
AS
1249 if (thisansp == ansp2)
1250 *ansp2_malloced = 1;
17a10319
UD
1251 }
1252 }
e9db92d3
CD
1253 /* We could end up with truncation if anscp was NULL
1254 (not allowed to change caller's buffer) and the
1255 response buffer size is too small. This isn't a
1256 reliable way to detect truncation because the ioctl
1257 may be an inaccurate report of the UDP message size.
1258 Therefore we use this only to issue debug output.
1259 To do truncation accurately with UDP we need
1260 MSG_TRUNC which is only available on Linux. We
1261 can abstract out the Linux-specific feature in the
1262 future to detect truncation. */
1263 if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
1264 Dprint(statp->options & RES_DEBUG,
1265 (stdout, ";; response may be truncated (UDP)\n")
1266 );
1267 }
1268
1eb946b9
UD
1269 HEADER *anhp = (HEADER *) *thisansp;
1270 socklen_t fromlen = sizeof(struct sockaddr_in6);
1271 assert (sizeof(from) <= fromlen);
1272 *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
1273 *thisanssizp, 0,
1274 (struct sockaddr *)&from, &fromlen);
a1ffb40e 1275 if (__glibc_unlikely (*thisresplenp <= 0)) {
17a10319
UD
1276 if (errno == EINTR || errno == EAGAIN) {
1277 need_recompute = 1;
1278 goto wait;
1279 }
1280 Perror(statp, stderr, "recvfrom", errno);
b66d837b 1281 return close_and_return_error (statp, resplen2);
17a10319 1282 }
e685e07d 1283 *gotsomewhere = 1;
a1ffb40e 1284 if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
17a10319
UD
1285 /*
1286 * Undersized message.
1287 */
1288 Dprint(statp->options & RES_DEBUG,
1289 (stdout, ";; undersized: %d\n",
a092b645 1290 *thisresplenp));
17a10319 1291 *terrno = EMSGSIZE;
b66d837b 1292 return close_and_return_error (statp, resplen2);
17a10319 1293 }
1eb946b9
UD
1294 if ((recvresp1 || hp->id != anhp->id)
1295 && (recvresp2 || hp2->id != anhp->id)) {
17a10319
UD
1296 /*
1297 * response from old query, ignore it.
1298 * XXX - potential security hazard could
1299 * be detected here.
1300 */
1301 DprintQ((statp->options & RES_DEBUG) ||
1302 (statp->pfcode & RES_PRF_REPLY),
1303 (stdout, ";; old answer:\n"),
94308fd0 1304 *thisansp,
a092b645
YD
1305 (*thisresplenp > *thisanssizp)
1306 ? *thisanssizp : *thisresplenp);
f433b06b 1307 goto wait;
e685e07d 1308 }
17a10319
UD
1309 if (!(statp->options & RES_INSECURE1) &&
1310 !res_ourserver_p(statp, &from)) {
1311 /*
1312 * response from wrong server? ignore it.
1313 * XXX - potential security hazard could
1314 * be detected here.
1315 */
1316 DprintQ((statp->options & RES_DEBUG) ||
1317 (statp->pfcode & RES_PRF_REPLY),
1318 (stdout, ";; not our server:\n"),
94308fd0 1319 *thisansp,
a092b645
YD
1320 (*thisresplenp > *thisanssizp)
1321 ? *thisanssizp : *thisresplenp);
17a10319 1322 goto wait;
0420d888 1323 }
2bbb7d5b
UD
1324#ifdef RES_USE_EDNS0
1325 if (anhp->rcode == FORMERR
1326 && (statp->options & RES_USE_EDNS0) != 0U) {
1327 /*
1eb946b9 1328 * Do not retry if the server does not understand
2bbb7d5b
UD
1329 * EDNS0. The case has to be captured here, as
1330 * FORMERR packet do not carry query section, hence
1331 * res_queriesmatch() returns 0.
1332 */
1333 DprintQ(statp->options & RES_DEBUG,
1334 (stdout,
1335 "server rejected query with EDNS0:\n"),
94308fd0 1336 *thisansp,
a092b645
YD
1337 (*thisresplenp > *thisanssizp)
1338 ? *thisanssizp : *thisresplenp);
2bbb7d5b
UD
1339 /* record the error */
1340 statp->_flags |= RES_F_EDNS0ERR;
b66d837b 1341 return close_and_return_error (statp, resplen2);
3a85895f 1342 }
2bbb7d5b 1343#endif
1eb946b9
UD
1344 if (!(statp->options & RES_INSECURE2)
1345 && (recvresp1 || !res_queriesmatch(buf, buf + buflen,
1346 *thisansp,
1347 *thisansp
1348 + *thisanssizp))
1349 && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
1350 *thisansp,
1351 *thisansp
1352 + *thisanssizp))) {
17a10319
UD
1353 /*
1354 * response contains wrong query? ignore it.
1355 * XXX - potential security hazard could
1356 * be detected here.
1357 */
1358 DprintQ((statp->options & RES_DEBUG) ||
1359 (statp->pfcode & RES_PRF_REPLY),
1360 (stdout, ";; wrong query name:\n"),
94308fd0 1361 *thisansp,
a092b645
YD
1362 (*thisresplenp > *thisanssizp)
1363 ? *thisanssizp : *thisresplenp);
f433b06b
UD
1364 goto wait;
1365 }
17a10319
UD
1366 if (anhp->rcode == SERVFAIL ||
1367 anhp->rcode == NOTIMP ||
1368 anhp->rcode == REFUSED) {
1369 DprintQ(statp->options & RES_DEBUG,
1370 (stdout, "server rejected query:\n"),
94308fd0 1371 *thisansp,
a092b645
YD
1372 (*thisresplenp > *thisanssizp)
1373 ? *thisanssizp : *thisresplenp);
e2003883 1374
16b293a7 1375 next_ns:
4769ae77
UD
1376 if (recvresp1 || (buf2 != NULL && recvresp2)) {
1377 *resplen2 = 0;
e28b969b 1378 return resplen;
4769ae77 1379 }
e2003883
UD
1380 if (buf2 != NULL)
1381 {
4769ae77
UD
1382 /* No data from the first reply. */
1383 resplen = 0;
e2003883 1384 /* We are waiting for a possible second reply. */
e2003883
UD
1385 if (hp->id == anhp->id)
1386 recvresp1 = 1;
1387 else
1388 recvresp2 = 1;
1389
1390 goto wait;
1391 }
1392
17a10319
UD
1393 /* don't retry if called from dig */
1394 if (!statp->pfcode)
b66d837b
FW
1395 return close_and_return_error (statp, resplen2);
1396 __res_iclose(statp, false);
17a10319 1397 }
359bb2ef
UD
1398 if (anhp->rcode == NOERROR && anhp->ancount == 0
1399 && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
1400 DprintQ(statp->options & RES_DEBUG,
1401 (stdout, "referred query:\n"),
94308fd0 1402 *thisansp,
a092b645
YD
1403 (*thisresplenp > *thisanssizp)
1404 ? *thisanssizp : *thisresplenp);
359bb2ef
UD
1405 goto next_ns;
1406 }
17a10319
UD
1407 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1408 /*
1409 * To get the rest of answer,
1410 * use TCP with same server.
1411 */
1412 Dprint(statp->options & RES_DEBUG,
1413 (stdout, ";; truncated answer\n"));
1414 *v_circuit = 1;
cb07f6f6 1415 __res_iclose(statp, false);
1eb946b9
UD
1416 // XXX if we have received one reply we could
1417 // XXX use it and not repeat it over TCP...
b66d837b
FW
1418 if (resplen2 != NULL)
1419 *resplen2 = 0;
17a10319
UD
1420 return (1);
1421 }
1eb946b9
UD
1422 /* Mark which reply we received. */
1423 if (recvresp1 == 0 && hp->id == anhp->id)
1424 recvresp1 = 1;
1425 else
1426 recvresp2 = 1;
1427 /* Repeat waiting if we have a second answer to arrive. */
ae061910 1428 if ((recvresp1 & recvresp2) == 0) {
c030f70c 1429 if (single_request) {
ae061910 1430 pfd[0].events = POLLOUT;
44d20bca
UD
1431 if (single_request_reopen) {
1432 __res_iclose (statp, false);
1433 retval = reopen (statp, terrno, ns);
1434 if (retval <= 0)
b66d837b
FW
1435 {
1436 if (resplen2 != NULL)
1437 *resplen2 = 0;
1438 return retval;
1439 }
f9d2d032 1440 pfd[0].fd = EXT(statp).nssocks[ns];
44d20bca
UD
1441 }
1442 }
1eb946b9 1443 goto wait;
ae061910 1444 }
b66d837b
FW
1445 /* All is well. We have received both responses (if
1446 two responses were requested). */
17a10319 1447 return (resplen);
b66d837b
FW
1448 } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
1449 /* Something went wrong. We can stop trying. */
1450 return close_and_return_error (statp, resplen2);
9cfe5381 1451 else {
4769ae77 1452 /* poll should not have returned > 0 in this case. */
9cfe5381
RM
1453 abort ();
1454 }
e685e07d
UD
1455}
1456
1457#ifdef DEBUG
1458static void
1459Aerror(const res_state statp, FILE *file, const char *string, int error,
020a9a23 1460 const struct sockaddr *address)
e685e07d
UD
1461{
1462 int save = errno;
1463
1464 if ((statp->options & RES_DEBUG) != 0) {
020a9a23 1465 char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
e685e07d
UD
1466
1467 fprintf(file, "res_send: %s ([%s].%u): %s\n",
1468 string,
e2a99d8e
UD
1469 (address->sa_family == AF_INET
1470 ? inet_ntop(address->sa_family,
1471 &((const struct sockaddr_in *) address)->sin_addr,
1472 tmp, sizeof tmp)
1473 : inet_ntop(address->sa_family,
1474 &((const struct sockaddr_in6 *) address)->sin6_addr,
1475 tmp, sizeof tmp)),
020a9a23
UD
1476 (address->sa_family == AF_INET
1477 ? ntohs(((struct sockaddr_in *) address)->sin_port)
1478 : address->sa_family == AF_INET6
1479 ? ntohs(((struct sockaddr_in6 *) address)->sin6_port)
1480 : 0),
e685e07d
UD
1481 strerror(error));
1482 }
1483 __set_errno (save);
1484}
1485
1486static void
1487Perror(const res_state statp, FILE *file, const char *string, int error) {
1488 int save = errno;
1489
1490 if ((statp->options & RES_DEBUG) != 0)
1491 fprintf(file, "res_send: %s: %s\n",
1492 string, strerror(error));
1493 __set_errno (save);
1494}
1495#endif
1496
1497static int
438e8239
UD
1498sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
1499 if (a1->sin6_family == a2->sin6_family) {
1500 if (a1->sin6_family == AF_INET)
1501 return ((((struct sockaddr_in *)a1)->sin_port ==
1502 ((struct sockaddr_in *)a2)->sin_port) &&
1503 (((struct sockaddr_in *)a1)->sin_addr.s_addr ==
1504 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
1505 else
1506 return ((a1->sin6_port == a2->sin6_port) &&
1507 !memcmp(&a1->sin6_addr, &a2->sin6_addr,
1508 sizeof (struct in6_addr)));
1509 }
1510 if (a1->sin6_family == AF_INET) {
1511 struct sockaddr_in6 *sap = a1;
1512 a1 = a2;
1513 a2 = sap;
1514 } /* assumes that AF_INET and AF_INET6 are the only possibilities */
1515 return ((a1->sin6_port == ((struct sockaddr_in *)a2)->sin_port) &&
1516 IN6_IS_ADDR_V4MAPPED(&a1->sin6_addr) &&
1517 (a1->sin6_addr.s6_addr32[3] ==
1518 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
1519}