Fix linknamespace parallel test failures.
[glibc.git] / resolv / res_send.c
blobe96d5d409d3aa570223b0adf18a9d7e477c4c74c
1 /* Copyright (C) 2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
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.
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.
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/>. */
19 * Copyright (c) 1985, 1989, 1993
20 * The Regents of the University of California. All rights reserved.
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.
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.
48 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
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.
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.
68 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
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.
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.
85 * Send query to name server and wait for reply.
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>
96 #include <netinet/in.h>
97 #include <arpa/nameser.h>
98 #include <arpa/inet.h>
99 #include <sys/ioctl.h>
101 #include <errno.h>
102 #include <fcntl.h>
103 #include <netdb.h>
104 #include <resolv.h>
105 #include <signal.h>
106 #include <stdio.h>
107 #include <stdlib.h>
108 #include <string.h>
109 #include <unistd.h>
110 #include <kernel-features.h>
111 #include <libc-internal.h>
113 #if PACKETSZ > 65536
114 #define MAXPACKET PACKETSZ
115 #else
116 #define MAXPACKET 65536
117 #endif
119 /* From ev_streams.c. */
121 static inline void
122 __attribute ((always_inline))
123 evConsIovec(void *buf, size_t cnt, struct iovec *vec) {
124 memset(vec, 0xf5, sizeof (*vec));
125 vec->iov_base = buf;
126 vec->iov_len = cnt;
129 /* From ev_timers.c. */
131 #define BILLION 1000000000
133 static inline void
134 evConsTime(struct timespec *res, time_t sec, long nsec) {
135 res->tv_sec = sec;
136 res->tv_nsec = nsec;
139 static inline void
140 evAddTime(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;
150 static inline void
151 evSubTime(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;
156 else {
157 res->tv_nsec = (BILLION
158 - subtrahend->tv_nsec + minuend->tv_nsec);
159 res->tv_sec--;
163 static int
164 evCmpTime(struct timespec a, struct timespec b) {
165 long x = a.tv_sec - b.tv_sec;
167 if (x == 0L)
168 x = a.tv_nsec - b.tv_nsec;
169 return (x < 0L ? (-1) : x > 0L ? (1) : (0));
172 static void
173 evNowTime(struct timespec *res) {
174 struct timeval now;
176 if (gettimeofday(&now, NULL) < 0)
177 evConsTime(res, 0, 0);
178 else
179 TIMEVAL_TO_TIMESPEC (&now, res);
183 /* Options. Leave them on. */
184 /* #undef DEBUG */
185 #include "res_debug.h"
187 #define EXT(res) ((res)->_u._ext)
189 /* Forward. */
191 static struct sockaddr *get_nsaddr (res_state, int);
192 static int send_vc(res_state, const u_char *, int,
193 const u_char *, int,
194 u_char **, int *, int *, int, u_char **,
195 u_char **, int *, int *, int *);
196 static int send_dg(res_state, const u_char *, int,
197 const u_char *, int,
198 u_char **, int *, int *, int,
199 int *, int *, u_char **,
200 u_char **, int *, int *, int *);
201 #ifdef DEBUG
202 static void Aerror(const res_state, FILE *, const char *, int,
203 const struct sockaddr *);
204 static void Perror(const res_state, FILE *, const char *, int);
205 #endif
206 static int sock_eq(struct sockaddr_in6 *, struct sockaddr_in6 *);
208 /* Public. */
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
220 res_ourserver_p(const res_state statp, const struct sockaddr_in6 *inp)
222 int ns;
224 if (inp->sin6_family == AF_INET) {
225 struct sockaddr_in *in4p = (struct sockaddr_in *) inp;
226 in_port_t port = in4p->sin_port;
227 in_addr_t addr = in4p->sin_addr.s_addr;
229 for (ns = 0; ns < statp->nscount; ns++) {
230 const struct sockaddr_in *srv =
231 (struct sockaddr_in *) get_nsaddr (statp, ns);
233 if ((srv->sin_family == AF_INET) &&
234 (srv->sin_port == port) &&
235 (srv->sin_addr.s_addr == INADDR_ANY ||
236 srv->sin_addr.s_addr == addr))
237 return (1);
239 } else if (inp->sin6_family == AF_INET6) {
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) &&
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);
252 return (0);
255 /* int
256 * res_nameinquery(name, type, class, buf, eom)
257 * look for (name,type,class) in the query section of packet (buf,eom)
258 * requires:
259 * buf + HFIXEDSZ <= eom
260 * returns:
261 * -1 : format error
262 * 0 : not found
263 * >0 : found
264 * author:
265 * paul vixie, 29may94
268 res_nameinquery(const char *name, int type, int class,
269 const u_char *buf, const u_char *eom)
271 const u_char *cp = buf + HFIXEDSZ;
272 int qdcount = ntohs(((HEADER*)buf)->qdcount);
274 while (qdcount-- > 0) {
275 char tname[MAXDNAME+1];
276 int n, ttype, tclass;
278 n = dn_expand(buf, eom, cp, tname, sizeof tname);
279 if (n < 0)
280 return (-1);
281 cp += n;
282 if (cp + 2 * INT16SZ > eom)
283 return (-1);
284 NS_GET16(ttype, cp);
285 NS_GET16(tclass, cp);
286 if (ttype == type && tclass == class &&
287 ns_samename(tname, name) == 1)
288 return (1);
290 return (0);
292 libresolv_hidden_def (res_nameinquery)
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
306 res_queriesmatch(const u_char *buf1, const u_char *eom1,
307 const u_char *buf2, const u_char *eom2)
309 if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
310 return (-1);
313 * Only header section present in replies to
314 * dynamic update packets.
316 if ((((HEADER *)buf1)->opcode == ns_o_update) &&
317 (((HEADER *)buf2)->opcode == ns_o_update))
318 return (1);
320 /* Note that we initially do not convert QDCOUNT to the host byte
321 order. We can compare it with the second buffer's QDCOUNT
322 value without doing this. */
323 int qdcount = ((HEADER*)buf1)->qdcount;
324 if (qdcount != ((HEADER*)buf2)->qdcount)
325 return (0);
327 qdcount = htons (qdcount);
328 const u_char *cp = buf1 + HFIXEDSZ;
330 while (qdcount-- > 0) {
331 char tname[MAXDNAME+1];
332 int n, ttype, tclass;
334 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
335 if (n < 0)
336 return (-1);
337 cp += n;
338 if (cp + 2 * INT16SZ > eom1)
339 return (-1);
340 NS_GET16(ttype, cp);
341 NS_GET16(tclass, cp);
342 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
343 return (0);
345 return (1);
347 libresolv_hidden_def (res_queriesmatch)
350 __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
351 const u_char *buf2, int buflen2,
352 u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
353 int *nansp2, int *resplen2, int *ansp2_malloced)
355 int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
357 if (statp->nscount == 0) {
358 __set_errno (ESRCH);
359 return (-1);
362 if (anssiz < (buf2 == NULL ? 1 : 2) * HFIXEDSZ) {
363 __set_errno (EINVAL);
364 return (-1);
367 DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
368 (stdout, ";; res_send()\n"), buf, buflen);
369 v_circuit = ((statp->options & RES_USEVC)
370 || buflen > PACKETSZ
371 || buflen2 > PACKETSZ);
372 gotsomewhere = 0;
373 terrno = ETIMEDOUT;
376 * If the ns_addr_list in the resolver context has changed, then
377 * invalidate our cached copy and the associated timing data.
379 if (EXT(statp).nscount != 0) {
380 int needclose = 0;
382 if (EXT(statp).nscount != statp->nscount)
383 needclose++;
384 else
385 for (ns = 0; ns < statp->nscount; ns++) {
386 if (statp->nsaddr_list[ns].sin_family != 0
387 && !sock_eq((struct sockaddr_in6 *)
388 &statp->nsaddr_list[ns],
389 EXT(statp).nsaddrs[ns]))
391 needclose++;
392 break;
395 if (needclose) {
396 __res_iclose(statp, false);
397 EXT(statp).nscount = 0;
402 * Maybe initialize our private copy of the ns_addr_list.
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] =
411 malloc(sizeof (struct sockaddr_in6));
412 if (EXT(statp).nsaddrs[ns] != NULL)
413 memset (mempcpy(EXT(statp).nsaddrs[ns],
414 &statp->nsaddr_list[ns],
415 sizeof (struct sockaddr_in)),
416 '\0',
417 sizeof (struct sockaddr_in6)
418 - sizeof (struct sockaddr_in));
420 EXT(statp).nscount = statp->nscount;
424 * Some resolvers want to even out the load on their nameservers.
425 * Note that RES_BLAST overrides RES_ROTATE.
427 if (__builtin_expect ((statp->options & RES_ROTATE) != 0, 0) &&
428 (statp->options & RES_BLAST) == 0) {
429 struct sockaddr_in ina;
430 struct sockaddr_in6 *inp;
431 int lastns = statp->nscount - 1;
432 int fd;
434 inp = EXT(statp).nsaddrs[0];
435 ina = statp->nsaddr_list[0];
436 fd = EXT(statp).nssocks[0];
437 for (ns = 0; ns < lastns; ns++) {
438 EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
439 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
440 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
442 EXT(statp).nsaddrs[lastns] = inp;
443 statp->nsaddr_list[lastns] = ina;
444 EXT(statp).nssocks[lastns] = fd;
448 * Send request, RETRY times, or until successful.
450 for (try = 0; try < statp->retry; try++) {
451 for (ns = 0; ns < statp->nscount; ns++)
453 #ifdef DEBUG
454 char tmpbuf[40];
455 struct sockaddr *nsap = get_nsaddr (statp, ns);
456 #endif
458 same_ns:
459 Dprint(statp->options & RES_DEBUG,
460 (stdout, ";; Querying server (# %d) address = %s\n",
461 ns + 1, inet_ntop(nsap->sa_family,
462 (nsap->sa_family == AF_INET6
463 ? (void *) &((struct sockaddr_in6 *) nsap)->sin6_addr
464 : (void *) &((struct sockaddr_in *) nsap)->sin_addr),
465 tmpbuf, sizeof (tmpbuf))));
467 if (__glibc_unlikely (v_circuit)) {
468 /* Use VC; at most one attempt per server. */
469 try = statp->retry;
470 n = send_vc(statp, buf, buflen, buf2, buflen2,
471 &ans, &anssiz, &terrno,
472 ns, ansp, ansp2, nansp2, resplen2,
473 ansp2_malloced);
474 if (n < 0)
475 return (-1);
476 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
477 goto next_ns;
478 } else {
479 /* Use datagrams. */
480 n = send_dg(statp, buf, buflen, buf2, buflen2,
481 &ans, &anssiz, &terrno,
482 ns, &v_circuit, &gotsomewhere, ansp,
483 ansp2, nansp2, resplen2, ansp2_malloced);
484 if (n < 0)
485 return (-1);
486 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
487 goto next_ns;
488 if (v_circuit)
489 // XXX Check whether both requests failed or
490 // XXX whether one has been answered successfully
491 goto same_ns;
494 resplen = n;
496 Dprint((statp->options & RES_DEBUG) ||
497 ((statp->pfcode & RES_PRF_REPLY) &&
498 (statp->pfcode & RES_PRF_HEAD1)),
499 (stdout, ";; got answer:\n"));
501 DprintQ((statp->options & RES_DEBUG) ||
502 (statp->pfcode & RES_PRF_REPLY),
503 (stdout, "%s", ""),
504 ans, (resplen > anssiz) ? anssiz : resplen);
505 if (buf2 != NULL) {
506 DprintQ((statp->options & RES_DEBUG) ||
507 (statp->pfcode & RES_PRF_REPLY),
508 (stdout, "%s", ""),
509 *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
513 * If we have temporarily opened a virtual circuit,
514 * or if we haven't been asked to keep a socket open,
515 * close the socket.
517 if ((v_circuit && (statp->options & RES_USEVC) == 0) ||
518 (statp->options & RES_STAYOPEN) == 0) {
519 __res_iclose(statp, false);
521 return (resplen);
522 next_ns: ;
523 } /*foreach ns*/
524 } /*foreach retry*/
525 __res_iclose(statp, false);
526 if (!v_circuit) {
527 if (!gotsomewhere)
528 __set_errno (ECONNREFUSED); /* no nameservers found */
529 else
530 __set_errno (ETIMEDOUT); /* no answer obtained */
531 } else
532 __set_errno (terrno);
533 return (-1);
537 res_nsend(res_state statp,
538 const u_char *buf, int buflen, u_char *ans, int anssiz)
540 return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
541 NULL, NULL, NULL, NULL, NULL);
543 libresolv_hidden_def (res_nsend)
545 /* Private */
547 static struct sockaddr *
548 get_nsaddr (res_state statp, int n)
551 if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
552 /* EXT(statp).nsaddrs[n] holds an address that is larger than
553 struct sockaddr, and user code did not update
554 statp->nsaddr_list[n]. */
555 return (struct sockaddr *) EXT(statp).nsaddrs[n];
556 else
557 /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
558 has the same content as EXT(statp).nsaddrs[n]. */
559 return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
562 /* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
563 is not NULL, and return zero. */
564 static int
565 __attribute__ ((warn_unused_result))
566 close_and_return_error (res_state statp, int *resplen2)
568 __res_iclose(statp, false);
569 if (resplen2 != NULL)
570 *resplen2 = 0;
571 return 0;
574 /* The send_vc function is responsible for sending a DNS query over TCP
575 to the nameserver numbered NS from the res_state STATP i.e.
576 EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
577 IPv6 queries at the same serially on the same socket.
579 Please note that for TCP there is no way to disable sending both
580 queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
581 and sends the queries serially and waits for the result after each
582 sent query. This implemetnation should be corrected to honour these
583 options.
585 Please also note that for TCP we send both queries over the same
586 socket one after another. This technically violates best practice
587 since the server is allowed to read the first query, respond, and
588 then close the socket (to service another client). If the server
589 does this, then the remaining second query in the socket data buffer
590 will cause the server to send the client an RST which will arrive
591 asynchronously and the client's OS will likely tear down the socket
592 receive buffer resulting in a potentially short read and lost
593 response data. This will force the client to retry the query again,
594 and this process may repeat until all servers and connection resets
595 are exhausted and then the query will fail. It's not known if this
596 happens with any frequency in real DNS server implementations. This
597 implementation should be corrected to use two sockets by default for
598 parallel queries.
600 The query stored in BUF of BUFLEN length is sent first followed by
601 the query stored in BUF2 of BUFLEN2 length. Queries are sent
602 serially on the same socket.
604 Answers to the query are stored firstly in *ANSP up to a max of
605 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
606 is non-NULL (to indicate that modifying the answer buffer is allowed)
607 then malloc is used to allocate a new response buffer and ANSCP and
608 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
609 are needed but ANSCP is NULL, then as much of the response as
610 possible is read into the buffer, but the results will be truncated.
611 When truncation happens because of a small answer buffer the DNS
612 packets header field TC will bet set to 1, indicating a truncated
613 message and the rest of the socket data will be read and discarded.
615 Answers to the query are stored secondly in *ANSP2 up to a max of
616 *ANSSIZP2 bytes, with the actual response length stored in
617 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
618 is non-NULL (required for a second query) then malloc is used to
619 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
620 size and *ANSP2_MALLOCED is set to 1.
622 The ANSP2_MALLOCED argument will eventually be removed as the
623 change in buffer pointer can be used to detect the buffer has
624 changed and that the caller should use free on the new buffer.
626 Note that the answers may arrive in any order from the server and
627 therefore the first and second answer buffers may not correspond to
628 the first and second queries.
630 It is not supported to call this function with a non-NULL ANSP2
631 but a NULL ANSCP. Put another way, you can call send_vc with a
632 single unmodifiable buffer or two modifiable buffers, but no other
633 combination is supported.
635 It is the caller's responsibility to free the malloc allocated
636 buffers by detecting that the pointers have changed from their
637 original values i.e. *ANSCP or *ANSP2 has changed.
639 If errors are encountered then *TERRNO is set to an appropriate
640 errno value and a zero result is returned for a recoverable error,
641 and a less-than zero result is returned for a non-recoverable error.
643 If no errors are encountered then *TERRNO is left unmodified and
644 a the length of the first response in bytes is returned. */
645 static int
646 send_vc(res_state statp,
647 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
648 u_char **ansp, int *anssizp,
649 int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
650 int *resplen2, int *ansp2_malloced)
652 const HEADER *hp = (HEADER *) buf;
653 const HEADER *hp2 = (HEADER *) buf2;
654 HEADER *anhp = (HEADER *) *ansp;
655 struct sockaddr *nsap = get_nsaddr (statp, ns);
656 int truncating, connreset, n;
657 /* On some architectures compiler might emit a warning indicating
658 'resplen' may be used uninitialized. However if buf2 == NULL
659 then this code won't be executed; if buf2 != NULL, then first
660 time round the loop recvresp1 and recvresp2 will be 0 so this
661 code won't be executed but "thisresplenp = &resplen;" followed
662 by "*thisresplenp = rlen;" will be executed so that subsequent
663 times round the loop resplen has been initialized. So this is
664 a false-positive.
666 DIAG_PUSH_NEEDS_COMMENT;
667 DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
668 int resplen;
669 DIAG_POP_NEEDS_COMMENT;
670 struct iovec iov[4];
671 u_short len;
672 u_short len2;
673 u_char *cp;
675 connreset = 0;
676 same_ns:
677 truncating = 0;
679 /* Are we still talking to whom we want to talk to? */
680 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
681 struct sockaddr_in6 peer;
682 socklen_t size = sizeof peer;
684 if (getpeername(statp->_vcsock,
685 (struct sockaddr *)&peer, &size) < 0 ||
686 !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
687 __res_iclose(statp, false);
688 statp->_flags &= ~RES_F_VC;
692 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
693 if (statp->_vcsock >= 0)
694 __res_iclose(statp, false);
696 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
697 if (statp->_vcsock < 0) {
698 *terrno = errno;
699 Perror(statp, stderr, "socket(vc)", errno);
700 if (resplen2 != NULL)
701 *resplen2 = 0;
702 return (-1);
704 __set_errno (0);
705 if (connect(statp->_vcsock, nsap,
706 nsap->sa_family == AF_INET
707 ? sizeof (struct sockaddr_in)
708 : sizeof (struct sockaddr_in6)) < 0) {
709 *terrno = errno;
710 Aerror(statp, stderr, "connect/vc", errno, nsap);
711 return close_and_return_error (statp, resplen2);
713 statp->_flags |= RES_F_VC;
717 * Send length & message
719 len = htons ((u_short) buflen);
720 evConsIovec(&len, INT16SZ, &iov[0]);
721 evConsIovec((void*)buf, buflen, &iov[1]);
722 int niov = 2;
723 ssize_t explen = INT16SZ + buflen;
724 if (buf2 != NULL) {
725 len2 = htons ((u_short) buflen2);
726 evConsIovec(&len2, INT16SZ, &iov[2]);
727 evConsIovec((void*)buf2, buflen2, &iov[3]);
728 niov = 4;
729 explen += INT16SZ + buflen2;
731 if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) {
732 *terrno = errno;
733 Perror(statp, stderr, "write failed", errno);
734 return close_and_return_error (statp, resplen2);
737 * Receive length & response
739 int recvresp1 = 0;
740 /* Skip the second response if there is no second query.
741 To do that we mark the second response as received. */
742 int recvresp2 = buf2 == NULL;
743 uint16_t rlen16;
744 read_len:
745 cp = (u_char *)&rlen16;
746 len = sizeof(rlen16);
747 while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, cp,
748 (int)len))) > 0) {
749 cp += n;
750 if ((len -= n) <= 0)
751 break;
753 if (n <= 0) {
754 *terrno = errno;
755 Perror(statp, stderr, "read failed", errno);
757 * A long running process might get its TCP
758 * connection reset if the remote server was
759 * restarted. Requery the server instead of
760 * trying a new one. When there is only one
761 * server, this means that a query might work
762 * instead of failing. We only allow one reset
763 * per query to prevent looping.
765 if (*terrno == ECONNRESET && !connreset)
767 __res_iclose (statp, false);
768 connreset = 1;
769 goto same_ns;
771 return close_and_return_error (statp, resplen2);
773 int rlen = ntohs (rlen16);
775 int *thisanssizp;
776 u_char **thisansp;
777 int *thisresplenp;
778 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
779 /* We have not received any responses
780 yet or we only have one response to
781 receive. */
782 thisanssizp = anssizp;
783 thisansp = anscp ?: ansp;
784 assert (anscp != NULL || ansp2 == NULL);
785 thisresplenp = &resplen;
786 } else {
787 thisanssizp = anssizp2;
788 thisansp = ansp2;
789 thisresplenp = resplen2;
791 anhp = (HEADER *) *thisansp;
793 *thisresplenp = rlen;
794 /* Is the answer buffer too small? */
795 if (*thisanssizp < rlen) {
796 /* If the current buffer is not the the static
797 user-supplied buffer then we can reallocate
798 it. */
799 if (thisansp != NULL && thisansp != ansp) {
800 /* Always allocate MAXPACKET, callers expect
801 this specific size. */
802 u_char *newp = malloc (MAXPACKET);
803 if (newp == NULL)
805 *terrno = ENOMEM;
806 return close_and_return_error (statp, resplen2);
808 *thisanssizp = MAXPACKET;
809 *thisansp = newp;
810 if (thisansp == ansp2)
811 *ansp2_malloced = 1;
812 anhp = (HEADER *) newp;
813 /* A uint16_t can't be larger than MAXPACKET
814 thus it's safe to allocate MAXPACKET but
815 read RLEN bytes instead. */
816 len = rlen;
817 } else {
818 Dprint(statp->options & RES_DEBUG,
819 (stdout, ";; response truncated\n")
821 truncating = 1;
822 len = *thisanssizp;
824 } else
825 len = rlen;
827 if (__glibc_unlikely (len < HFIXEDSZ)) {
829 * Undersized message.
831 Dprint(statp->options & RES_DEBUG,
832 (stdout, ";; undersized: %d\n", len));
833 *terrno = EMSGSIZE;
834 return close_and_return_error (statp, resplen2);
837 cp = *thisansp;
838 while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
839 cp += n;
840 len -= n;
842 if (__glibc_unlikely (n <= 0)) {
843 *terrno = errno;
844 Perror(statp, stderr, "read(vc)", errno);
845 return close_and_return_error (statp, resplen2);
847 if (__glibc_unlikely (truncating)) {
849 * Flush rest of answer so connection stays in synch.
851 anhp->tc = 1;
852 len = rlen - *thisanssizp;
853 while (len != 0) {
854 char junk[PACKETSZ];
856 n = read(statp->_vcsock, junk,
857 (len > sizeof junk) ? sizeof junk : len);
858 if (n > 0)
859 len -= n;
860 else
861 break;
865 * If the calling application has bailed out of
866 * a previous call and failed to arrange to have
867 * the circuit closed or the server has got
868 * itself confused, then drop the packet and
869 * wait for the correct one.
871 if ((recvresp1 || hp->id != anhp->id)
872 && (recvresp2 || hp2->id != anhp->id)) {
873 DprintQ((statp->options & RES_DEBUG) ||
874 (statp->pfcode & RES_PRF_REPLY),
875 (stdout, ";; old answer (unexpected):\n"),
876 *thisansp,
877 (rlen > *thisanssizp) ? *thisanssizp: rlen);
878 goto read_len;
881 /* Mark which reply we received. */
882 if (recvresp1 == 0 && hp->id == anhp->id)
883 recvresp1 = 1;
884 else
885 recvresp2 = 1;
886 /* Repeat waiting if we have a second answer to arrive. */
887 if ((recvresp1 & recvresp2) == 0)
888 goto read_len;
891 * All is well, or the error is fatal. Signal that the
892 * next nameserver ought not be tried.
894 return resplen;
897 static int
898 reopen (res_state statp, int *terrno, int ns)
900 if (EXT(statp).nssocks[ns] == -1) {
901 struct sockaddr *nsap = get_nsaddr (statp, ns);
902 socklen_t slen;
904 /* only try IPv6 if IPv6 NS and if not failed before */
905 if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
906 EXT(statp).nssocks[ns]
907 = socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, 0);
908 if (EXT(statp).nssocks[ns] < 0)
909 statp->ipv6_unavail = errno == EAFNOSUPPORT;
910 slen = sizeof (struct sockaddr_in6);
911 } else if (nsap->sa_family == AF_INET) {
912 EXT(statp).nssocks[ns]
913 = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);
914 slen = sizeof (struct sockaddr_in);
916 if (EXT(statp).nssocks[ns] < 0) {
917 *terrno = errno;
918 Perror(statp, stderr, "socket(dg)", errno);
919 return (-1);
923 * On a 4.3BSD+ machine (client and server,
924 * actually), sending to a nameserver datagram
925 * port with no nameserver will cause an
926 * ICMP port unreachable message to be returned.
927 * If our datagram socket is "connected" to the
928 * server, we get an ECONNREFUSED error on the next
929 * socket operation, and select returns if the
930 * error message is received. We can thus detect
931 * the absence of a nameserver without timing out.
933 /* With GCC 5.3 when compiling with -Os the compiler
934 emits a warning that slen may be used uninitialized,
935 but that is never true. Both slen and
936 EXT(statp).nssocks[ns] are initialized together or
937 the function return -1 before control flow reaches
938 the call to connect with slen. */
939 DIAG_PUSH_NEEDS_COMMENT;
940 DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
941 if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
942 DIAG_POP_NEEDS_COMMENT;
943 Aerror(statp, stderr, "connect(dg)", errno, nsap);
944 __res_iclose(statp, false);
945 return (0);
949 return 1;
952 /* The send_dg function is responsible for sending a DNS query over UDP
953 to the nameserver numbered NS from the res_state STATP i.e.
954 EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
955 along with the ability to send the query in parallel for both stacks
956 (default) or serially (RES_SINGLKUP). It also supports serial lookup
957 with a close and reopen of the socket used to talk to the server
958 (RES_SNGLKUPREOP) to work around broken name servers.
960 The query stored in BUF of BUFLEN length is sent first followed by
961 the query stored in BUF2 of BUFLEN2 length. Queries are sent
962 in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
964 Answers to the query are stored firstly in *ANSP up to a max of
965 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
966 is non-NULL (to indicate that modifying the answer buffer is allowed)
967 then malloc is used to allocate a new response buffer and ANSCP and
968 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
969 are needed but ANSCP is NULL, then as much of the response as
970 possible is read into the buffer, but the results will be truncated.
971 When truncation happens because of a small answer buffer the DNS
972 packets header field TC will bet set to 1, indicating a truncated
973 message, while the rest of the UDP packet is discarded.
975 Answers to the query are stored secondly in *ANSP2 up to a max of
976 *ANSSIZP2 bytes, with the actual response length stored in
977 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
978 is non-NULL (required for a second query) then malloc is used to
979 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
980 size and *ANSP2_MALLOCED is set to 1.
982 The ANSP2_MALLOCED argument will eventually be removed as the
983 change in buffer pointer can be used to detect the buffer has
984 changed and that the caller should use free on the new buffer.
986 Note that the answers may arrive in any order from the server and
987 therefore the first and second answer buffers may not correspond to
988 the first and second queries.
990 It is not supported to call this function with a non-NULL ANSP2
991 but a NULL ANSCP. Put another way, you can call send_vc with a
992 single unmodifiable buffer or two modifiable buffers, but no other
993 combination is supported.
995 It is the caller's responsibility to free the malloc allocated
996 buffers by detecting that the pointers have changed from their
997 original values i.e. *ANSCP or *ANSP2 has changed.
999 If an answer is truncated because of UDP datagram DNS limits then
1000 *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
1001 the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
1002 if any progress was made reading a response from the nameserver and
1003 is used by the caller to distinguish between ECONNREFUSED and
1004 ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
1006 If errors are encountered then *TERRNO is set to an appropriate
1007 errno value and a zero result is returned for a recoverable error,
1008 and a less-than zero result is returned for a non-recoverable error.
1010 If no errors are encountered then *TERRNO is left unmodified and
1011 a the length of the first response in bytes is returned. */
1012 static int
1013 send_dg(res_state statp,
1014 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
1015 u_char **ansp, int *anssizp,
1016 int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
1017 u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
1019 const HEADER *hp = (HEADER *) buf;
1020 const HEADER *hp2 = (HEADER *) buf2;
1021 struct timespec now, timeout, finish;
1022 struct pollfd pfd[1];
1023 int ptimeout;
1024 struct sockaddr_in6 from;
1025 int resplen = 0;
1026 int n;
1029 * Compute time for the total operation.
1031 int seconds = (statp->retrans << ns);
1032 if (ns > 0)
1033 seconds /= statp->nscount;
1034 if (seconds <= 0)
1035 seconds = 1;
1036 bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
1037 bool single_request = (((statp->options & RES_SNGLKUP) != 0)
1038 | single_request_reopen);
1039 int save_gotsomewhere = *gotsomewhere;
1041 int retval;
1042 retry_reopen:
1043 retval = reopen (statp, terrno, ns);
1044 if (retval <= 0)
1046 if (resplen2 != NULL)
1047 *resplen2 = 0;
1048 return retval;
1050 retry:
1051 evNowTime(&now);
1052 evConsTime(&timeout, seconds, 0);
1053 evAddTime(&finish, &now, &timeout);
1054 int need_recompute = 0;
1055 int nwritten = 0;
1056 int recvresp1 = 0;
1057 /* Skip the second response if there is no second query.
1058 To do that we mark the second response as received. */
1059 int recvresp2 = buf2 == NULL;
1060 pfd[0].fd = EXT(statp).nssocks[ns];
1061 pfd[0].events = POLLOUT;
1062 wait:
1063 if (need_recompute) {
1064 recompute_resend:
1065 evNowTime(&now);
1066 if (evCmpTime(finish, now) <= 0) {
1067 poll_err_out:
1068 Perror(statp, stderr, "poll", errno);
1069 return close_and_return_error (statp, resplen2);
1071 evSubTime(&timeout, &finish, &now);
1072 need_recompute = 0;
1074 /* Convert struct timespec in milliseconds. */
1075 ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
1077 n = 0;
1078 if (nwritten == 0)
1079 n = __poll (pfd, 1, 0);
1080 if (__glibc_unlikely (n == 0)) {
1081 n = __poll (pfd, 1, ptimeout);
1082 need_recompute = 1;
1084 if (n == 0) {
1085 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
1086 if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
1088 /* There are quite a few broken name servers out
1089 there which don't handle two outstanding
1090 requests from the same source. There are also
1091 broken firewall settings. If we time out after
1092 having received one answer switch to the mode
1093 where we send the second request only once we
1094 have received the first answer. */
1095 if (!single_request)
1097 statp->options |= RES_SNGLKUP;
1098 single_request = true;
1099 *gotsomewhere = save_gotsomewhere;
1100 goto retry;
1102 else if (!single_request_reopen)
1104 statp->options |= RES_SNGLKUPREOP;
1105 single_request_reopen = true;
1106 *gotsomewhere = save_gotsomewhere;
1107 __res_iclose (statp, false);
1108 goto retry_reopen;
1111 *resplen2 = 1;
1112 return resplen;
1115 *gotsomewhere = 1;
1116 if (resplen2 != NULL)
1117 *resplen2 = 0;
1118 return 0;
1120 if (n < 0) {
1121 if (errno == EINTR)
1122 goto recompute_resend;
1124 goto poll_err_out;
1126 __set_errno (0);
1127 if (pfd[0].revents & POLLOUT) {
1128 #ifndef __ASSUME_SENDMMSG
1129 static int have_sendmmsg;
1130 #else
1131 # define have_sendmmsg 1
1132 #endif
1133 if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
1134 && !single_request)
1136 struct iovec iov[2];
1137 struct mmsghdr reqs[2];
1138 reqs[0].msg_hdr.msg_name = NULL;
1139 reqs[0].msg_hdr.msg_namelen = 0;
1140 reqs[0].msg_hdr.msg_iov = &iov[0];
1141 reqs[0].msg_hdr.msg_iovlen = 1;
1142 iov[0].iov_base = (void *) buf;
1143 iov[0].iov_len = buflen;
1144 reqs[0].msg_hdr.msg_control = NULL;
1145 reqs[0].msg_hdr.msg_controllen = 0;
1147 reqs[1].msg_hdr.msg_name = NULL;
1148 reqs[1].msg_hdr.msg_namelen = 0;
1149 reqs[1].msg_hdr.msg_iov = &iov[1];
1150 reqs[1].msg_hdr.msg_iovlen = 1;
1151 iov[1].iov_base = (void *) buf2;
1152 iov[1].iov_len = buflen2;
1153 reqs[1].msg_hdr.msg_control = NULL;
1154 reqs[1].msg_hdr.msg_controllen = 0;
1156 int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
1157 if (__glibc_likely (ndg == 2))
1159 if (reqs[0].msg_len != buflen
1160 || reqs[1].msg_len != buflen2)
1161 goto fail_sendmmsg;
1163 pfd[0].events = POLLIN;
1164 nwritten += 2;
1166 else if (ndg == 1 && reqs[0].msg_len == buflen)
1167 goto just_one;
1168 else if (ndg < 0 && (errno == EINTR || errno == EAGAIN))
1169 goto recompute_resend;
1170 else
1172 #ifndef __ASSUME_SENDMMSG
1173 if (__glibc_unlikely (have_sendmmsg == 0))
1175 if (ndg < 0 && errno == ENOSYS)
1177 have_sendmmsg = -1;
1178 goto try_send;
1180 have_sendmmsg = 1;
1182 #endif
1184 fail_sendmmsg:
1185 Perror(statp, stderr, "sendmmsg", errno);
1186 return close_and_return_error (statp, resplen2);
1189 else
1191 ssize_t sr;
1192 #ifndef __ASSUME_SENDMMSG
1193 try_send:
1194 #endif
1195 if (nwritten != 0)
1196 sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
1197 else
1198 sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
1200 if (sr != (nwritten != 0 ? buflen2 : buflen)) {
1201 if (errno == EINTR || errno == EAGAIN)
1202 goto recompute_resend;
1203 Perror(statp, stderr, "send", errno);
1204 return close_and_return_error (statp, resplen2);
1206 just_one:
1207 if (nwritten != 0 || buf2 == NULL || single_request)
1208 pfd[0].events = POLLIN;
1209 else
1210 pfd[0].events = POLLIN | POLLOUT;
1211 ++nwritten;
1213 goto wait;
1214 } else if (pfd[0].revents & POLLIN) {
1215 int *thisanssizp;
1216 u_char **thisansp;
1217 int *thisresplenp;
1219 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
1220 /* We have not received any responses
1221 yet or we only have one response to
1222 receive. */
1223 thisanssizp = anssizp;
1224 thisansp = anscp ?: ansp;
1225 assert (anscp != NULL || ansp2 == NULL);
1226 thisresplenp = &resplen;
1227 } else {
1228 thisanssizp = anssizp2;
1229 thisansp = ansp2;
1230 thisresplenp = resplen2;
1233 if (*thisanssizp < MAXPACKET
1234 /* If the current buffer is not the the static
1235 user-supplied buffer then we can reallocate
1236 it. */
1237 && (thisansp != NULL && thisansp != ansp)
1238 #ifdef FIONREAD
1239 /* Is the size too small? */
1240 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
1241 || *thisanssizp < *thisresplenp)
1242 #endif
1244 /* Always allocate MAXPACKET, callers expect
1245 this specific size. */
1246 u_char *newp = malloc (MAXPACKET);
1247 if (newp != NULL) {
1248 *thisanssizp = MAXPACKET;
1249 *thisansp = newp;
1250 if (thisansp == ansp2)
1251 *ansp2_malloced = 1;
1254 /* We could end up with truncation if anscp was NULL
1255 (not allowed to change caller's buffer) and the
1256 response buffer size is too small. This isn't a
1257 reliable way to detect truncation because the ioctl
1258 may be an inaccurate report of the UDP message size.
1259 Therefore we use this only to issue debug output.
1260 To do truncation accurately with UDP we need
1261 MSG_TRUNC which is only available on Linux. We
1262 can abstract out the Linux-specific feature in the
1263 future to detect truncation. */
1264 if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
1265 Dprint(statp->options & RES_DEBUG,
1266 (stdout, ";; response may be truncated (UDP)\n")
1270 HEADER *anhp = (HEADER *) *thisansp;
1271 socklen_t fromlen = sizeof(struct sockaddr_in6);
1272 assert (sizeof(from) <= fromlen);
1273 *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
1274 *thisanssizp, 0,
1275 (struct sockaddr *)&from, &fromlen);
1276 if (__glibc_unlikely (*thisresplenp <= 0)) {
1277 if (errno == EINTR || errno == EAGAIN) {
1278 need_recompute = 1;
1279 goto wait;
1281 Perror(statp, stderr, "recvfrom", errno);
1282 return close_and_return_error (statp, resplen2);
1284 *gotsomewhere = 1;
1285 if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
1287 * Undersized message.
1289 Dprint(statp->options & RES_DEBUG,
1290 (stdout, ";; undersized: %d\n",
1291 *thisresplenp));
1292 *terrno = EMSGSIZE;
1293 return close_and_return_error (statp, resplen2);
1295 if ((recvresp1 || hp->id != anhp->id)
1296 && (recvresp2 || hp2->id != anhp->id)) {
1298 * response from old query, ignore it.
1299 * XXX - potential security hazard could
1300 * be detected here.
1302 DprintQ((statp->options & RES_DEBUG) ||
1303 (statp->pfcode & RES_PRF_REPLY),
1304 (stdout, ";; old answer:\n"),
1305 *thisansp,
1306 (*thisresplenp > *thisanssizp)
1307 ? *thisanssizp : *thisresplenp);
1308 goto wait;
1310 if (!(statp->options & RES_INSECURE1) &&
1311 !res_ourserver_p(statp, &from)) {
1313 * response from wrong server? ignore it.
1314 * XXX - potential security hazard could
1315 * be detected here.
1317 DprintQ((statp->options & RES_DEBUG) ||
1318 (statp->pfcode & RES_PRF_REPLY),
1319 (stdout, ";; not our server:\n"),
1320 *thisansp,
1321 (*thisresplenp > *thisanssizp)
1322 ? *thisanssizp : *thisresplenp);
1323 goto wait;
1325 #ifdef RES_USE_EDNS0
1326 if (anhp->rcode == FORMERR
1327 && (statp->options & RES_USE_EDNS0) != 0U) {
1329 * Do not retry if the server does not understand
1330 * EDNS0. The case has to be captured here, as
1331 * FORMERR packet do not carry query section, hence
1332 * res_queriesmatch() returns 0.
1334 DprintQ(statp->options & RES_DEBUG,
1335 (stdout,
1336 "server rejected query with EDNS0:\n"),
1337 *thisansp,
1338 (*thisresplenp > *thisanssizp)
1339 ? *thisanssizp : *thisresplenp);
1340 /* record the error */
1341 statp->_flags |= RES_F_EDNS0ERR;
1342 return close_and_return_error (statp, resplen2);
1344 #endif
1345 if (!(statp->options & RES_INSECURE2)
1346 && (recvresp1 || !res_queriesmatch(buf, buf + buflen,
1347 *thisansp,
1348 *thisansp
1349 + *thisanssizp))
1350 && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
1351 *thisansp,
1352 *thisansp
1353 + *thisanssizp))) {
1355 * response contains wrong query? ignore it.
1356 * XXX - potential security hazard could
1357 * be detected here.
1359 DprintQ((statp->options & RES_DEBUG) ||
1360 (statp->pfcode & RES_PRF_REPLY),
1361 (stdout, ";; wrong query name:\n"),
1362 *thisansp,
1363 (*thisresplenp > *thisanssizp)
1364 ? *thisanssizp : *thisresplenp);
1365 goto wait;
1367 if (anhp->rcode == SERVFAIL ||
1368 anhp->rcode == NOTIMP ||
1369 anhp->rcode == REFUSED) {
1370 DprintQ(statp->options & RES_DEBUG,
1371 (stdout, "server rejected query:\n"),
1372 *thisansp,
1373 (*thisresplenp > *thisanssizp)
1374 ? *thisanssizp : *thisresplenp);
1376 next_ns:
1377 if (recvresp1 || (buf2 != NULL && recvresp2)) {
1378 *resplen2 = 0;
1379 return resplen;
1381 if (buf2 != NULL)
1383 /* No data from the first reply. */
1384 resplen = 0;
1385 /* We are waiting for a possible second reply. */
1386 if (hp->id == anhp->id)
1387 recvresp1 = 1;
1388 else
1389 recvresp2 = 1;
1391 goto wait;
1394 /* don't retry if called from dig */
1395 if (!statp->pfcode)
1396 return close_and_return_error (statp, resplen2);
1397 __res_iclose(statp, false);
1399 if (anhp->rcode == NOERROR && anhp->ancount == 0
1400 && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
1401 DprintQ(statp->options & RES_DEBUG,
1402 (stdout, "referred query:\n"),
1403 *thisansp,
1404 (*thisresplenp > *thisanssizp)
1405 ? *thisanssizp : *thisresplenp);
1406 goto next_ns;
1408 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1410 * To get the rest of answer,
1411 * use TCP with same server.
1413 Dprint(statp->options & RES_DEBUG,
1414 (stdout, ";; truncated answer\n"));
1415 *v_circuit = 1;
1416 __res_iclose(statp, false);
1417 // XXX if we have received one reply we could
1418 // XXX use it and not repeat it over TCP...
1419 if (resplen2 != NULL)
1420 *resplen2 = 0;
1421 return (1);
1423 /* Mark which reply we received. */
1424 if (recvresp1 == 0 && hp->id == anhp->id)
1425 recvresp1 = 1;
1426 else
1427 recvresp2 = 1;
1428 /* Repeat waiting if we have a second answer to arrive. */
1429 if ((recvresp1 & recvresp2) == 0) {
1430 if (single_request) {
1431 pfd[0].events = POLLOUT;
1432 if (single_request_reopen) {
1433 __res_iclose (statp, false);
1434 retval = reopen (statp, terrno, ns);
1435 if (retval <= 0)
1437 if (resplen2 != NULL)
1438 *resplen2 = 0;
1439 return retval;
1441 pfd[0].fd = EXT(statp).nssocks[ns];
1444 goto wait;
1446 /* All is well. We have received both responses (if
1447 two responses were requested). */
1448 return (resplen);
1449 } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
1450 /* Something went wrong. We can stop trying. */
1451 return close_and_return_error (statp, resplen2);
1452 else {
1453 /* poll should not have returned > 0 in this case. */
1454 abort ();
1458 #ifdef DEBUG
1459 static void
1460 Aerror(const res_state statp, FILE *file, const char *string, int error,
1461 const struct sockaddr *address)
1463 int save = errno;
1465 if ((statp->options & RES_DEBUG) != 0) {
1466 char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
1468 fprintf(file, "res_send: %s ([%s].%u): %s\n",
1469 string,
1470 (address->sa_family == AF_INET
1471 ? inet_ntop(address->sa_family,
1472 &((const struct sockaddr_in *) address)->sin_addr,
1473 tmp, sizeof tmp)
1474 : inet_ntop(address->sa_family,
1475 &((const struct sockaddr_in6 *) address)->sin6_addr,
1476 tmp, sizeof tmp)),
1477 (address->sa_family == AF_INET
1478 ? ntohs(((struct sockaddr_in *) address)->sin_port)
1479 : address->sa_family == AF_INET6
1480 ? ntohs(((struct sockaddr_in6 *) address)->sin6_port)
1481 : 0),
1482 strerror(error));
1484 __set_errno (save);
1487 static void
1488 Perror(const res_state statp, FILE *file, const char *string, int error) {
1489 int save = errno;
1491 if ((statp->options & RES_DEBUG) != 0)
1492 fprintf(file, "res_send: %s: %s\n",
1493 string, strerror(error));
1494 __set_errno (save);
1496 #endif
1498 static int
1499 sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
1500 if (a1->sin6_family == a2->sin6_family) {
1501 if (a1->sin6_family == AF_INET)
1502 return ((((struct sockaddr_in *)a1)->sin_port ==
1503 ((struct sockaddr_in *)a2)->sin_port) &&
1504 (((struct sockaddr_in *)a1)->sin_addr.s_addr ==
1505 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
1506 else
1507 return ((a1->sin6_port == a2->sin6_port) &&
1508 !memcmp(&a1->sin6_addr, &a2->sin6_addr,
1509 sizeof (struct in6_addr)));
1511 if (a1->sin6_family == AF_INET) {
1512 struct sockaddr_in6 *sap = a1;
1513 a1 = a2;
1514 a2 = sap;
1515 } /* assumes that AF_INET and AF_INET6 are the only possibilities */
1516 return ((a1->sin6_port == ((struct sockaddr_in *)a2)->sin_port) &&
1517 IN6_IS_ADDR_V4MAPPED(&a1->sin6_addr) &&
1518 (a1->sin6_addr.s6_addr32[3] ==
1519 ((struct sockaddr_in *)a2)->sin_addr.s_addr));