Update old tunables framework document/script.
[glibc.git] / resolv / res_send.c
blob28c4cabfcb403f6fc9d9b22ee79ee3a7e47a52fe
1 /* Copyright (C) 2016-2017 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-diag.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 struct sockaddr_in ina;
429 struct sockaddr_in6 *inp;
430 int lastns = statp->nscount - 1;
431 int fd;
433 inp = EXT(statp).nsaddrs[0];
434 ina = statp->nsaddr_list[0];
435 fd = EXT(statp).nssocks[0];
436 for (ns = 0; ns < lastns; ns++) {
437 EXT(statp).nsaddrs[ns] = EXT(statp).nsaddrs[ns + 1];
438 statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
439 EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
441 EXT(statp).nsaddrs[lastns] = inp;
442 statp->nsaddr_list[lastns] = ina;
443 EXT(statp).nssocks[lastns] = fd;
447 * Send request, RETRY times, or until successful.
449 for (try = 0; try < statp->retry; try++) {
450 for (ns = 0; ns < statp->nscount; ns++)
452 #ifdef DEBUG
453 char tmpbuf[40];
454 struct sockaddr *nsap = get_nsaddr (statp, ns);
455 #endif
457 same_ns:
458 Dprint(statp->options & RES_DEBUG,
459 (stdout, ";; Querying server (# %d) address = %s\n",
460 ns + 1, inet_ntop(nsap->sa_family,
461 (nsap->sa_family == AF_INET6
462 ? (void *) &((struct sockaddr_in6 *) nsap)->sin6_addr
463 : (void *) &((struct sockaddr_in *) nsap)->sin_addr),
464 tmpbuf, sizeof (tmpbuf))));
466 if (__glibc_unlikely (v_circuit)) {
467 /* Use VC; at most one attempt per server. */
468 try = statp->retry;
469 n = send_vc(statp, buf, buflen, buf2, buflen2,
470 &ans, &anssiz, &terrno,
471 ns, ansp, ansp2, nansp2, resplen2,
472 ansp2_malloced);
473 if (n < 0)
474 return (-1);
475 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
476 goto next_ns;
477 } else {
478 /* Use datagrams. */
479 n = send_dg(statp, buf, buflen, buf2, buflen2,
480 &ans, &anssiz, &terrno,
481 ns, &v_circuit, &gotsomewhere, ansp,
482 ansp2, nansp2, resplen2, ansp2_malloced);
483 if (n < 0)
484 return (-1);
485 if (n == 0 && (buf2 == NULL || *resplen2 == 0))
486 goto next_ns;
487 if (v_circuit)
488 // XXX Check whether both requests failed or
489 // XXX whether one has been answered successfully
490 goto same_ns;
493 resplen = n;
495 Dprint((statp->options & RES_DEBUG) ||
496 ((statp->pfcode & RES_PRF_REPLY) &&
497 (statp->pfcode & RES_PRF_HEAD1)),
498 (stdout, ";; got answer:\n"));
500 DprintQ((statp->options & RES_DEBUG) ||
501 (statp->pfcode & RES_PRF_REPLY),
502 (stdout, "%s", ""),
503 ans, (resplen > anssiz) ? anssiz : resplen);
504 if (buf2 != NULL) {
505 DprintQ((statp->options & RES_DEBUG) ||
506 (statp->pfcode & RES_PRF_REPLY),
507 (stdout, "%s", ""),
508 *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
512 * If we have temporarily opened a virtual circuit,
513 * or if we haven't been asked to keep a socket open,
514 * close the socket.
516 if ((v_circuit && (statp->options & RES_USEVC) == 0) ||
517 (statp->options & RES_STAYOPEN) == 0) {
518 __res_iclose(statp, false);
520 return (resplen);
521 next_ns: ;
522 } /*foreach ns*/
523 } /*foreach retry*/
524 __res_iclose(statp, false);
525 if (!v_circuit) {
526 if (!gotsomewhere)
527 __set_errno (ECONNREFUSED); /* no nameservers found */
528 else
529 __set_errno (ETIMEDOUT); /* no answer obtained */
530 } else
531 __set_errno (terrno);
532 return (-1);
536 res_nsend(res_state statp,
537 const u_char *buf, int buflen, u_char *ans, int anssiz)
539 return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
540 NULL, NULL, NULL, NULL, NULL);
542 libresolv_hidden_def (res_nsend)
544 /* Private */
546 static struct sockaddr *
547 get_nsaddr (res_state statp, int n)
550 if (statp->nsaddr_list[n].sin_family == 0 && EXT(statp).nsaddrs[n] != NULL)
551 /* EXT(statp).nsaddrs[n] holds an address that is larger than
552 struct sockaddr, and user code did not update
553 statp->nsaddr_list[n]. */
554 return (struct sockaddr *) EXT(statp).nsaddrs[n];
555 else
556 /* User code updated statp->nsaddr_list[n], or statp->nsaddr_list[n]
557 has the same content as EXT(statp).nsaddrs[n]. */
558 return (struct sockaddr *) (void *) &statp->nsaddr_list[n];
561 /* Close the resolver structure, assign zero to *RESPLEN2 if RESPLEN2
562 is not NULL, and return zero. */
563 static int
564 __attribute__ ((warn_unused_result))
565 close_and_return_error (res_state statp, int *resplen2)
567 __res_iclose(statp, false);
568 if (resplen2 != NULL)
569 *resplen2 = 0;
570 return 0;
573 /* The send_vc function is responsible for sending a DNS query over TCP
574 to the nameserver numbered NS from the res_state STATP i.e.
575 EXT(statp).nssocks[ns]. The function supports sending both IPv4 and
576 IPv6 queries at the same serially on the same socket.
578 Please note that for TCP there is no way to disable sending both
579 queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
580 and sends the queries serially and waits for the result after each
581 sent query. This implementation should be corrected to honour these
582 options.
584 Please also note that for TCP we send both queries over the same
585 socket one after another. This technically violates best practice
586 since the server is allowed to read the first query, respond, and
587 then close the socket (to service another client). If the server
588 does this, then the remaining second query in the socket data buffer
589 will cause the server to send the client an RST which will arrive
590 asynchronously and the client's OS will likely tear down the socket
591 receive buffer resulting in a potentially short read and lost
592 response data. This will force the client to retry the query again,
593 and this process may repeat until all servers and connection resets
594 are exhausted and then the query will fail. It's not known if this
595 happens with any frequency in real DNS server implementations. This
596 implementation should be corrected to use two sockets by default for
597 parallel queries.
599 The query stored in BUF of BUFLEN length is sent first followed by
600 the query stored in BUF2 of BUFLEN2 length. Queries are sent
601 serially on the same socket.
603 Answers to the query are stored firstly in *ANSP up to a max of
604 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
605 is non-NULL (to indicate that modifying the answer buffer is allowed)
606 then malloc is used to allocate a new response buffer and ANSCP and
607 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
608 are needed but ANSCP is NULL, then as much of the response as
609 possible is read into the buffer, but the results will be truncated.
610 When truncation happens because of a small answer buffer the DNS
611 packets header field TC will bet set to 1, indicating a truncated
612 message and the rest of the socket data will be read and discarded.
614 Answers to the query are stored secondly in *ANSP2 up to a max of
615 *ANSSIZP2 bytes, with the actual response length stored in
616 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
617 is non-NULL (required for a second query) then malloc is used to
618 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
619 size and *ANSP2_MALLOCED is set to 1.
621 The ANSP2_MALLOCED argument will eventually be removed as the
622 change in buffer pointer can be used to detect the buffer has
623 changed and that the caller should use free on the new buffer.
625 Note that the answers may arrive in any order from the server and
626 therefore the first and second answer buffers may not correspond to
627 the first and second queries.
629 It is not supported to call this function with a non-NULL ANSP2
630 but a NULL ANSCP. Put another way, you can call send_vc with a
631 single unmodifiable buffer or two modifiable buffers, but no other
632 combination is supported.
634 It is the caller's responsibility to free the malloc allocated
635 buffers by detecting that the pointers have changed from their
636 original values i.e. *ANSCP or *ANSP2 has changed.
638 If errors are encountered then *TERRNO is set to an appropriate
639 errno value and a zero result is returned for a recoverable error,
640 and a less-than zero result is returned for a non-recoverable error.
642 If no errors are encountered then *TERRNO is left unmodified and
643 a the length of the first response in bytes is returned. */
644 static int
645 send_vc(res_state statp,
646 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
647 u_char **ansp, int *anssizp,
648 int *terrno, int ns, u_char **anscp, u_char **ansp2, int *anssizp2,
649 int *resplen2, int *ansp2_malloced)
651 const HEADER *hp = (HEADER *) buf;
652 const HEADER *hp2 = (HEADER *) buf2;
653 HEADER *anhp = (HEADER *) *ansp;
654 struct sockaddr *nsap = get_nsaddr (statp, ns);
655 int truncating, connreset, n;
656 /* On some architectures compiler might emit a warning indicating
657 'resplen' may be used uninitialized. However if buf2 == NULL
658 then this code won't be executed; if buf2 != NULL, then first
659 time round the loop recvresp1 and recvresp2 will be 0 so this
660 code won't be executed but "thisresplenp = &resplen;" followed
661 by "*thisresplenp = rlen;" will be executed so that subsequent
662 times round the loop resplen has been initialized. So this is
663 a false-positive.
665 DIAG_PUSH_NEEDS_COMMENT;
666 DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
667 int resplen;
668 DIAG_POP_NEEDS_COMMENT;
669 struct iovec iov[4];
670 u_short len;
671 u_short len2;
672 u_char *cp;
674 connreset = 0;
675 same_ns:
676 truncating = 0;
678 /* Are we still talking to whom we want to talk to? */
679 if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
680 struct sockaddr_in6 peer;
681 socklen_t size = sizeof peer;
683 if (getpeername(statp->_vcsock,
684 (struct sockaddr *)&peer, &size) < 0 ||
685 !sock_eq(&peer, (struct sockaddr_in6 *) nsap)) {
686 __res_iclose(statp, false);
687 statp->_flags &= ~RES_F_VC;
691 if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
692 if (statp->_vcsock >= 0)
693 __res_iclose(statp, false);
695 statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
696 if (statp->_vcsock < 0) {
697 *terrno = errno;
698 Perror(statp, stderr, "socket(vc)", errno);
699 if (resplen2 != NULL)
700 *resplen2 = 0;
701 return (-1);
703 __set_errno (0);
704 if (connect(statp->_vcsock, nsap,
705 nsap->sa_family == AF_INET
706 ? sizeof (struct sockaddr_in)
707 : sizeof (struct sockaddr_in6)) < 0) {
708 *terrno = errno;
709 Aerror(statp, stderr, "connect/vc", errno, nsap);
710 return close_and_return_error (statp, resplen2);
712 statp->_flags |= RES_F_VC;
716 * Send length & message
718 len = htons ((u_short) buflen);
719 evConsIovec(&len, INT16SZ, &iov[0]);
720 evConsIovec((void*)buf, buflen, &iov[1]);
721 int niov = 2;
722 ssize_t explen = INT16SZ + buflen;
723 if (buf2 != NULL) {
724 len2 = htons ((u_short) buflen2);
725 evConsIovec(&len2, INT16SZ, &iov[2]);
726 evConsIovec((void*)buf2, buflen2, &iov[3]);
727 niov = 4;
728 explen += INT16SZ + buflen2;
730 if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) {
731 *terrno = errno;
732 Perror(statp, stderr, "write failed", errno);
733 return close_and_return_error (statp, resplen2);
736 * Receive length & response
738 int recvresp1 = 0;
739 /* Skip the second response if there is no second query.
740 To do that we mark the second response as received. */
741 int recvresp2 = buf2 == NULL;
742 uint16_t rlen16;
743 read_len:
744 cp = (u_char *)&rlen16;
745 len = sizeof(rlen16);
746 while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, cp,
747 (int)len))) > 0) {
748 cp += n;
749 if ((len -= n) <= 0)
750 break;
752 if (n <= 0) {
753 *terrno = errno;
754 Perror(statp, stderr, "read failed", errno);
756 * A long running process might get its TCP
757 * connection reset if the remote server was
758 * restarted. Requery the server instead of
759 * trying a new one. When there is only one
760 * server, this means that a query might work
761 * instead of failing. We only allow one reset
762 * per query to prevent looping.
764 if (*terrno == ECONNRESET && !connreset)
766 __res_iclose (statp, false);
767 connreset = 1;
768 goto same_ns;
770 return close_and_return_error (statp, resplen2);
772 int rlen = ntohs (rlen16);
774 int *thisanssizp;
775 u_char **thisansp;
776 int *thisresplenp;
777 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
778 /* We have not received any responses
779 yet or we only have one response to
780 receive. */
781 thisanssizp = anssizp;
782 thisansp = anscp ?: ansp;
783 assert (anscp != NULL || ansp2 == NULL);
784 thisresplenp = &resplen;
785 } else {
786 thisanssizp = anssizp2;
787 thisansp = ansp2;
788 thisresplenp = resplen2;
790 anhp = (HEADER *) *thisansp;
792 *thisresplenp = rlen;
793 /* Is the answer buffer too small? */
794 if (*thisanssizp < rlen) {
795 /* If the current buffer is not the the static
796 user-supplied buffer then we can reallocate
797 it. */
798 if (thisansp != NULL && thisansp != ansp) {
799 /* Always allocate MAXPACKET, callers expect
800 this specific size. */
801 u_char *newp = malloc (MAXPACKET);
802 if (newp == NULL)
804 *terrno = ENOMEM;
805 return close_and_return_error (statp, resplen2);
807 *thisanssizp = MAXPACKET;
808 *thisansp = newp;
809 if (thisansp == ansp2)
810 *ansp2_malloced = 1;
811 anhp = (HEADER *) newp;
812 /* A uint16_t can't be larger than MAXPACKET
813 thus it's safe to allocate MAXPACKET but
814 read RLEN bytes instead. */
815 len = rlen;
816 } else {
817 Dprint(statp->options & RES_DEBUG,
818 (stdout, ";; response truncated\n")
820 truncating = 1;
821 len = *thisanssizp;
823 } else
824 len = rlen;
826 if (__glibc_unlikely (len < HFIXEDSZ)) {
828 * Undersized message.
830 Dprint(statp->options & RES_DEBUG,
831 (stdout, ";; undersized: %d\n", len));
832 *terrno = EMSGSIZE;
833 return close_and_return_error (statp, resplen2);
836 cp = *thisansp;
837 while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
838 cp += n;
839 len -= n;
841 if (__glibc_unlikely (n <= 0)) {
842 *terrno = errno;
843 Perror(statp, stderr, "read(vc)", errno);
844 return close_and_return_error (statp, resplen2);
846 if (__glibc_unlikely (truncating)) {
848 * Flush rest of answer so connection stays in synch.
850 anhp->tc = 1;
851 len = rlen - *thisanssizp;
852 while (len != 0) {
853 char junk[PACKETSZ];
855 n = read(statp->_vcsock, junk,
856 (len > sizeof junk) ? sizeof junk : len);
857 if (n > 0)
858 len -= n;
859 else
860 break;
864 * If the calling application has bailed out of
865 * a previous call and failed to arrange to have
866 * the circuit closed or the server has got
867 * itself confused, then drop the packet and
868 * wait for the correct one.
870 if ((recvresp1 || hp->id != anhp->id)
871 && (recvresp2 || hp2->id != anhp->id)) {
872 DprintQ((statp->options & RES_DEBUG) ||
873 (statp->pfcode & RES_PRF_REPLY),
874 (stdout, ";; old answer (unexpected):\n"),
875 *thisansp,
876 (rlen > *thisanssizp) ? *thisanssizp: rlen);
877 goto read_len;
880 /* Mark which reply we received. */
881 if (recvresp1 == 0 && hp->id == anhp->id)
882 recvresp1 = 1;
883 else
884 recvresp2 = 1;
885 /* Repeat waiting if we have a second answer to arrive. */
886 if ((recvresp1 & recvresp2) == 0)
887 goto read_len;
890 * All is well, or the error is fatal. Signal that the
891 * next nameserver ought not be tried.
893 return resplen;
896 static int
897 reopen (res_state statp, int *terrno, int ns)
899 if (EXT(statp).nssocks[ns] == -1) {
900 struct sockaddr *nsap = get_nsaddr (statp, ns);
901 socklen_t slen;
903 /* only try IPv6 if IPv6 NS and if not failed before */
904 if (nsap->sa_family == AF_INET6 && !statp->ipv6_unavail) {
905 EXT(statp).nssocks[ns]
906 = socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, 0);
907 if (EXT(statp).nssocks[ns] < 0)
908 statp->ipv6_unavail = errno == EAFNOSUPPORT;
909 slen = sizeof (struct sockaddr_in6);
910 } else if (nsap->sa_family == AF_INET) {
911 EXT(statp).nssocks[ns]
912 = socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);
913 slen = sizeof (struct sockaddr_in);
915 if (EXT(statp).nssocks[ns] < 0) {
916 *terrno = errno;
917 Perror(statp, stderr, "socket(dg)", errno);
918 return (-1);
922 * On a 4.3BSD+ machine (client and server,
923 * actually), sending to a nameserver datagram
924 * port with no nameserver will cause an
925 * ICMP port unreachable message to be returned.
926 * If our datagram socket is "connected" to the
927 * server, we get an ECONNREFUSED error on the next
928 * socket operation, and select returns if the
929 * error message is received. We can thus detect
930 * the absence of a nameserver without timing out.
932 /* With GCC 5.3 when compiling with -Os the compiler
933 emits a warning that slen may be used uninitialized,
934 but that is never true. Both slen and
935 EXT(statp).nssocks[ns] are initialized together or
936 the function return -1 before control flow reaches
937 the call to connect with slen. */
938 DIAG_PUSH_NEEDS_COMMENT;
939 DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
940 if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
941 DIAG_POP_NEEDS_COMMENT;
942 Aerror(statp, stderr, "connect(dg)", errno, nsap);
943 __res_iclose(statp, false);
944 return (0);
948 return 1;
951 /* The send_dg function is responsible for sending a DNS query over UDP
952 to the nameserver numbered NS from the res_state STATP i.e.
953 EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
954 along with the ability to send the query in parallel for both stacks
955 (default) or serially (RES_SINGLKUP). It also supports serial lookup
956 with a close and reopen of the socket used to talk to the server
957 (RES_SNGLKUPREOP) to work around broken name servers.
959 The query stored in BUF of BUFLEN length is sent first followed by
960 the query stored in BUF2 of BUFLEN2 length. Queries are sent
961 in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
963 Answers to the query are stored firstly in *ANSP up to a max of
964 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
965 is non-NULL (to indicate that modifying the answer buffer is allowed)
966 then malloc is used to allocate a new response buffer and ANSCP and
967 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
968 are needed but ANSCP is NULL, then as much of the response as
969 possible is read into the buffer, but the results will be truncated.
970 When truncation happens because of a small answer buffer the DNS
971 packets header field TC will bet set to 1, indicating a truncated
972 message, while the rest of the UDP packet is discarded.
974 Answers to the query are stored secondly in *ANSP2 up to a max of
975 *ANSSIZP2 bytes, with the actual response length stored in
976 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
977 is non-NULL (required for a second query) then malloc is used to
978 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
979 size and *ANSP2_MALLOCED is set to 1.
981 The ANSP2_MALLOCED argument will eventually be removed as the
982 change in buffer pointer can be used to detect the buffer has
983 changed and that the caller should use free on the new buffer.
985 Note that the answers may arrive in any order from the server and
986 therefore the first and second answer buffers may not correspond to
987 the first and second queries.
989 It is not supported to call this function with a non-NULL ANSP2
990 but a NULL ANSCP. Put another way, you can call send_vc with a
991 single unmodifiable buffer or two modifiable buffers, but no other
992 combination is supported.
994 It is the caller's responsibility to free the malloc allocated
995 buffers by detecting that the pointers have changed from their
996 original values i.e. *ANSCP or *ANSP2 has changed.
998 If an answer is truncated because of UDP datagram DNS limits then
999 *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
1000 the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
1001 if any progress was made reading a response from the nameserver and
1002 is used by the caller to distinguish between ECONNREFUSED and
1003 ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
1005 If errors are encountered then *TERRNO is set to an appropriate
1006 errno value and a zero result is returned for a recoverable error,
1007 and a less-than zero result is returned for a non-recoverable error.
1009 If no errors are encountered then *TERRNO is left unmodified and
1010 a the length of the first response in bytes is returned. */
1011 static int
1012 send_dg(res_state statp,
1013 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
1014 u_char **ansp, int *anssizp,
1015 int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
1016 u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
1018 const HEADER *hp = (HEADER *) buf;
1019 const HEADER *hp2 = (HEADER *) buf2;
1020 struct timespec now, timeout, finish;
1021 struct pollfd pfd[1];
1022 int ptimeout;
1023 struct sockaddr_in6 from;
1024 int resplen = 0;
1025 int n;
1028 * Compute time for the total operation.
1030 int seconds = (statp->retrans << ns);
1031 if (ns > 0)
1032 seconds /= statp->nscount;
1033 if (seconds <= 0)
1034 seconds = 1;
1035 bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
1036 bool single_request = (((statp->options & RES_SNGLKUP) != 0)
1037 | single_request_reopen);
1038 int save_gotsomewhere = *gotsomewhere;
1040 int retval;
1041 retry_reopen:
1042 retval = reopen (statp, terrno, ns);
1043 if (retval <= 0)
1045 if (resplen2 != NULL)
1046 *resplen2 = 0;
1047 return retval;
1049 retry:
1050 evNowTime(&now);
1051 evConsTime(&timeout, seconds, 0);
1052 evAddTime(&finish, &now, &timeout);
1053 int need_recompute = 0;
1054 int nwritten = 0;
1055 int recvresp1 = 0;
1056 /* Skip the second response if there is no second query.
1057 To do that we mark the second response as received. */
1058 int recvresp2 = buf2 == NULL;
1059 pfd[0].fd = EXT(statp).nssocks[ns];
1060 pfd[0].events = POLLOUT;
1061 wait:
1062 if (need_recompute) {
1063 recompute_resend:
1064 evNowTime(&now);
1065 if (evCmpTime(finish, now) <= 0) {
1066 poll_err_out:
1067 Perror(statp, stderr, "poll", errno);
1068 return close_and_return_error (statp, resplen2);
1070 evSubTime(&timeout, &finish, &now);
1071 need_recompute = 0;
1073 /* Convert struct timespec in milliseconds. */
1074 ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
1076 n = 0;
1077 if (nwritten == 0)
1078 n = __poll (pfd, 1, 0);
1079 if (__glibc_unlikely (n == 0)) {
1080 n = __poll (pfd, 1, ptimeout);
1081 need_recompute = 1;
1083 if (n == 0) {
1084 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
1085 if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
1087 /* There are quite a few broken name servers out
1088 there which don't handle two outstanding
1089 requests from the same source. There are also
1090 broken firewall settings. If we time out after
1091 having received one answer switch to the mode
1092 where we send the second request only once we
1093 have received the first answer. */
1094 if (!single_request)
1096 statp->options |= RES_SNGLKUP;
1097 single_request = true;
1098 *gotsomewhere = save_gotsomewhere;
1099 goto retry;
1101 else if (!single_request_reopen)
1103 statp->options |= RES_SNGLKUPREOP;
1104 single_request_reopen = true;
1105 *gotsomewhere = save_gotsomewhere;
1106 __res_iclose (statp, false);
1107 goto retry_reopen;
1110 *resplen2 = 1;
1111 return resplen;
1114 *gotsomewhere = 1;
1115 if (resplen2 != NULL)
1116 *resplen2 = 0;
1117 return 0;
1119 if (n < 0) {
1120 if (errno == EINTR)
1121 goto recompute_resend;
1123 goto poll_err_out;
1125 __set_errno (0);
1126 if (pfd[0].revents & POLLOUT) {
1127 #ifndef __ASSUME_SENDMMSG
1128 static int have_sendmmsg;
1129 #else
1130 # define have_sendmmsg 1
1131 #endif
1132 if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
1133 && !single_request)
1135 struct iovec iov[2];
1136 struct mmsghdr reqs[2];
1137 reqs[0].msg_hdr.msg_name = NULL;
1138 reqs[0].msg_hdr.msg_namelen = 0;
1139 reqs[0].msg_hdr.msg_iov = &iov[0];
1140 reqs[0].msg_hdr.msg_iovlen = 1;
1141 iov[0].iov_base = (void *) buf;
1142 iov[0].iov_len = buflen;
1143 reqs[0].msg_hdr.msg_control = NULL;
1144 reqs[0].msg_hdr.msg_controllen = 0;
1146 reqs[1].msg_hdr.msg_name = NULL;
1147 reqs[1].msg_hdr.msg_namelen = 0;
1148 reqs[1].msg_hdr.msg_iov = &iov[1];
1149 reqs[1].msg_hdr.msg_iovlen = 1;
1150 iov[1].iov_base = (void *) buf2;
1151 iov[1].iov_len = buflen2;
1152 reqs[1].msg_hdr.msg_control = NULL;
1153 reqs[1].msg_hdr.msg_controllen = 0;
1155 int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
1156 if (__glibc_likely (ndg == 2))
1158 if (reqs[0].msg_len != buflen
1159 || reqs[1].msg_len != buflen2)
1160 goto fail_sendmmsg;
1162 pfd[0].events = POLLIN;
1163 nwritten += 2;
1165 else if (ndg == 1 && reqs[0].msg_len == buflen)
1166 goto just_one;
1167 else if (ndg < 0 && (errno == EINTR || errno == EAGAIN))
1168 goto recompute_resend;
1169 else
1171 #ifndef __ASSUME_SENDMMSG
1172 if (__glibc_unlikely (have_sendmmsg == 0))
1174 if (ndg < 0 && errno == ENOSYS)
1176 have_sendmmsg = -1;
1177 goto try_send;
1179 have_sendmmsg = 1;
1181 #endif
1183 fail_sendmmsg:
1184 Perror(statp, stderr, "sendmmsg", errno);
1185 return close_and_return_error (statp, resplen2);
1188 else
1190 ssize_t sr;
1191 #ifndef __ASSUME_SENDMMSG
1192 try_send:
1193 #endif
1194 if (nwritten != 0)
1195 sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
1196 else
1197 sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
1199 if (sr != (nwritten != 0 ? buflen2 : buflen)) {
1200 if (errno == EINTR || errno == EAGAIN)
1201 goto recompute_resend;
1202 Perror(statp, stderr, "send", errno);
1203 return close_and_return_error (statp, resplen2);
1205 just_one:
1206 if (nwritten != 0 || buf2 == NULL || single_request)
1207 pfd[0].events = POLLIN;
1208 else
1209 pfd[0].events = POLLIN | POLLOUT;
1210 ++nwritten;
1212 goto wait;
1213 } else if (pfd[0].revents & POLLIN) {
1214 int *thisanssizp;
1215 u_char **thisansp;
1216 int *thisresplenp;
1218 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
1219 /* We have not received any responses
1220 yet or we only have one response to
1221 receive. */
1222 thisanssizp = anssizp;
1223 thisansp = anscp ?: ansp;
1224 assert (anscp != NULL || ansp2 == NULL);
1225 thisresplenp = &resplen;
1226 } else {
1227 thisanssizp = anssizp2;
1228 thisansp = ansp2;
1229 thisresplenp = resplen2;
1232 if (*thisanssizp < MAXPACKET
1233 /* If the current buffer is not the the static
1234 user-supplied buffer then we can reallocate
1235 it. */
1236 && (thisansp != NULL && thisansp != ansp)
1237 #ifdef FIONREAD
1238 /* Is the size too small? */
1239 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
1240 || *thisanssizp < *thisresplenp)
1241 #endif
1243 /* Always allocate MAXPACKET, callers expect
1244 this specific size. */
1245 u_char *newp = malloc (MAXPACKET);
1246 if (newp != NULL) {
1247 *thisanssizp = MAXPACKET;
1248 *thisansp = newp;
1249 if (thisansp == ansp2)
1250 *ansp2_malloced = 1;
1253 /* We could end up with truncation if anscp was NULL
1254 (not allowed to change caller's buffer) and the
1255 response buffer size is too small. This isn't a
1256 reliable way to detect truncation because the ioctl
1257 may be an inaccurate report of the UDP message size.
1258 Therefore we use this only to issue debug output.
1259 To do truncation accurately with UDP we need
1260 MSG_TRUNC which is only available on Linux. We
1261 can abstract out the Linux-specific feature in the
1262 future to detect truncation. */
1263 if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
1264 Dprint(statp->options & RES_DEBUG,
1265 (stdout, ";; response may be truncated (UDP)\n")
1269 HEADER *anhp = (HEADER *) *thisansp;
1270 socklen_t fromlen = sizeof(struct sockaddr_in6);
1271 assert (sizeof(from) <= fromlen);
1272 *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
1273 *thisanssizp, 0,
1274 (struct sockaddr *)&from, &fromlen);
1275 if (__glibc_unlikely (*thisresplenp <= 0)) {
1276 if (errno == EINTR || errno == EAGAIN) {
1277 need_recompute = 1;
1278 goto wait;
1280 Perror(statp, stderr, "recvfrom", errno);
1281 return close_and_return_error (statp, resplen2);
1283 *gotsomewhere = 1;
1284 if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
1286 * Undersized message.
1288 Dprint(statp->options & RES_DEBUG,
1289 (stdout, ";; undersized: %d\n",
1290 *thisresplenp));
1291 *terrno = EMSGSIZE;
1292 return close_and_return_error (statp, resplen2);
1294 if ((recvresp1 || hp->id != anhp->id)
1295 && (recvresp2 || hp2->id != anhp->id)) {
1297 * response from old query, ignore it.
1298 * XXX - potential security hazard could
1299 * be detected here.
1301 DprintQ((statp->options & RES_DEBUG) ||
1302 (statp->pfcode & RES_PRF_REPLY),
1303 (stdout, ";; old answer:\n"),
1304 *thisansp,
1305 (*thisresplenp > *thisanssizp)
1306 ? *thisanssizp : *thisresplenp);
1307 goto wait;
1309 if (!(statp->options & RES_INSECURE1) &&
1310 !res_ourserver_p(statp, &from)) {
1312 * response from wrong server? ignore it.
1313 * XXX - potential security hazard could
1314 * be detected here.
1316 DprintQ((statp->options & RES_DEBUG) ||
1317 (statp->pfcode & RES_PRF_REPLY),
1318 (stdout, ";; not our server:\n"),
1319 *thisansp,
1320 (*thisresplenp > *thisanssizp)
1321 ? *thisanssizp : *thisresplenp);
1322 goto wait;
1324 #ifdef RES_USE_EDNS0
1325 if (anhp->rcode == FORMERR
1326 && (statp->options & RES_USE_EDNS0) != 0U) {
1328 * Do not retry if the server does not understand
1329 * EDNS0. The case has to be captured here, as
1330 * FORMERR packet do not carry query section, hence
1331 * res_queriesmatch() returns 0.
1333 DprintQ(statp->options & RES_DEBUG,
1334 (stdout,
1335 "server rejected query with EDNS0:\n"),
1336 *thisansp,
1337 (*thisresplenp > *thisanssizp)
1338 ? *thisanssizp : *thisresplenp);
1339 /* record the error */
1340 statp->_flags |= RES_F_EDNS0ERR;
1341 return close_and_return_error (statp, resplen2);
1343 #endif
1344 if (!(statp->options & RES_INSECURE2)
1345 && (recvresp1 || !res_queriesmatch(buf, buf + buflen,
1346 *thisansp,
1347 *thisansp
1348 + *thisanssizp))
1349 && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
1350 *thisansp,
1351 *thisansp
1352 + *thisanssizp))) {
1354 * response contains wrong query? ignore it.
1355 * XXX - potential security hazard could
1356 * be detected here.
1358 DprintQ((statp->options & RES_DEBUG) ||
1359 (statp->pfcode & RES_PRF_REPLY),
1360 (stdout, ";; wrong query name:\n"),
1361 *thisansp,
1362 (*thisresplenp > *thisanssizp)
1363 ? *thisanssizp : *thisresplenp);
1364 goto wait;
1366 if (anhp->rcode == SERVFAIL ||
1367 anhp->rcode == NOTIMP ||
1368 anhp->rcode == REFUSED) {
1369 DprintQ(statp->options & RES_DEBUG,
1370 (stdout, "server rejected query:\n"),
1371 *thisansp,
1372 (*thisresplenp > *thisanssizp)
1373 ? *thisanssizp : *thisresplenp);
1375 next_ns:
1376 if (recvresp1 || (buf2 != NULL && recvresp2)) {
1377 *resplen2 = 0;
1378 return resplen;
1380 if (buf2 != NULL)
1382 /* No data from the first reply. */
1383 resplen = 0;
1384 /* We are waiting for a possible second reply. */
1385 if (hp->id == anhp->id)
1386 recvresp1 = 1;
1387 else
1388 recvresp2 = 1;
1390 goto wait;
1393 /* don't retry if called from dig */
1394 if (!statp->pfcode)
1395 return close_and_return_error (statp, resplen2);
1396 __res_iclose(statp, false);
1398 if (anhp->rcode == NOERROR && anhp->ancount == 0
1399 && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
1400 DprintQ(statp->options & RES_DEBUG,
1401 (stdout, "referred query:\n"),
1402 *thisansp,
1403 (*thisresplenp > *thisanssizp)
1404 ? *thisanssizp : *thisresplenp);
1405 goto next_ns;
1407 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1409 * To get the rest of answer,
1410 * use TCP with same server.
1412 Dprint(statp->options & RES_DEBUG,
1413 (stdout, ";; truncated answer\n"));
1414 *v_circuit = 1;
1415 __res_iclose(statp, false);
1416 // XXX if we have received one reply we could
1417 // XXX use it and not repeat it over TCP...
1418 if (resplen2 != NULL)
1419 *resplen2 = 0;
1420 return (1);
1422 /* Mark which reply we received. */
1423 if (recvresp1 == 0 && hp->id == anhp->id)
1424 recvresp1 = 1;
1425 else
1426 recvresp2 = 1;
1427 /* Repeat waiting if we have a second answer to arrive. */
1428 if ((recvresp1 & recvresp2) == 0) {
1429 if (single_request) {
1430 pfd[0].events = POLLOUT;
1431 if (single_request_reopen) {
1432 __res_iclose (statp, false);
1433 retval = reopen (statp, terrno, ns);
1434 if (retval <= 0)
1436 if (resplen2 != NULL)
1437 *resplen2 = 0;
1438 return retval;
1440 pfd[0].fd = EXT(statp).nssocks[ns];
1443 goto wait;
1445 /* All is well. We have received both responses (if
1446 two responses were requested). */
1447 return (resplen);
1448 } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
1449 /* Something went wrong. We can stop trying. */
1450 return close_and_return_error (statp, resplen2);
1451 else {
1452 /* poll should not have returned > 0 in this case. */
1453 abort ();
1457 #ifdef DEBUG
1458 static void
1459 Aerror(const res_state statp, FILE *file, const char *string, int error,
1460 const struct sockaddr *address)
1462 int save = errno;
1464 if ((statp->options & RES_DEBUG) != 0) {
1465 char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
1467 fprintf(file, "res_send: %s ([%s].%u): %s\n",
1468 string,
1469 (address->sa_family == AF_INET
1470 ? inet_ntop(address->sa_family,
1471 &((const struct sockaddr_in *) address)->sin_addr,
1472 tmp, sizeof tmp)
1473 : inet_ntop(address->sa_family,
1474 &((const struct sockaddr_in6 *) address)->sin6_addr,
1475 tmp, sizeof tmp)),
1476 (address->sa_family == AF_INET
1477 ? ntohs(((struct sockaddr_in *) address)->sin_port)
1478 : address->sa_family == AF_INET6
1479 ? ntohs(((struct sockaddr_in6 *) address)->sin6_port)
1480 : 0),
1481 strerror(error));
1483 __set_errno (save);
1486 static void
1487 Perror(const res_state statp, FILE *file, const char *string, int error) {
1488 int save = errno;
1490 if ((statp->options & RES_DEBUG) != 0)
1491 fprintf(file, "res_send: %s: %s\n",
1492 string, strerror(error));
1493 __set_errno (save);
1495 #endif
1497 static int
1498 sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
1499 if (a1->sin6_family == a2->sin6_family) {
1500 if (a1->sin6_family == AF_INET)
1501 return ((((struct sockaddr_in *)a1)->sin_port ==
1502 ((struct sockaddr_in *)a2)->sin_port) &&
1503 (((struct sockaddr_in *)a1)->sin_addr.s_addr ==
1504 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
1505 else
1506 return ((a1->sin6_port == a2->sin6_port) &&
1507 !memcmp(&a1->sin6_addr, &a2->sin6_addr,
1508 sizeof (struct in6_addr)));
1510 if (a1->sin6_family == AF_INET) {
1511 struct sockaddr_in6 *sap = a1;
1512 a1 = a2;
1513 a2 = sap;
1514 } /* assumes that AF_INET and AF_INET6 are the only possibilities */
1515 return ((a1->sin6_port == ((struct sockaddr_in *)a2)->sin_port) &&
1516 IN6_IS_ADDR_V4MAPPED(&a1->sin6_addr) &&
1517 (a1->sin6_addr.s6_addr32[3] ==
1518 ((struct sockaddr_in *)a2)->sin_addr.s_addr));