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