Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false...
[glibc.git] / resolv / res_send.c
blob6d46bb2c15d84f3f8eff4c1b1854df0ffebf6d18
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 if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
934 Aerror(statp, stderr, "connect(dg)", errno, nsap);
935 __res_iclose(statp, false);
936 return (0);
940 return 1;
943 /* The send_dg function is responsible for sending a DNS query over UDP
944 to the nameserver numbered NS from the res_state STATP i.e.
945 EXT(statp).nssocks[ns]. The function supports IPv4 and IPv6 queries
946 along with the ability to send the query in parallel for both stacks
947 (default) or serially (RES_SINGLKUP). It also supports serial lookup
948 with a close and reopen of the socket used to talk to the server
949 (RES_SNGLKUPREOP) to work around broken name servers.
951 The query stored in BUF of BUFLEN length is sent first followed by
952 the query stored in BUF2 of BUFLEN2 length. Queries are sent
953 in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
955 Answers to the query are stored firstly in *ANSP up to a max of
956 *ANSSIZP bytes. If more than *ANSSIZP bytes are needed and ANSCP
957 is non-NULL (to indicate that modifying the answer buffer is allowed)
958 then malloc is used to allocate a new response buffer and ANSCP and
959 ANSP will both point to the new buffer. If more than *ANSSIZP bytes
960 are needed but ANSCP is NULL, then as much of the response as
961 possible is read into the buffer, but the results will be truncated.
962 When truncation happens because of a small answer buffer the DNS
963 packets header field TC will bet set to 1, indicating a truncated
964 message, while the rest of the UDP packet is discarded.
966 Answers to the query are stored secondly in *ANSP2 up to a max of
967 *ANSSIZP2 bytes, with the actual response length stored in
968 *RESPLEN2. If more than *ANSSIZP bytes are needed and ANSP2
969 is non-NULL (required for a second query) then malloc is used to
970 allocate a new response buffer, *ANSSIZP2 is set to the new buffer
971 size and *ANSP2_MALLOCED is set to 1.
973 The ANSP2_MALLOCED argument will eventually be removed as the
974 change in buffer pointer can be used to detect the buffer has
975 changed and that the caller should use free on the new buffer.
977 Note that the answers may arrive in any order from the server and
978 therefore the first and second answer buffers may not correspond to
979 the first and second queries.
981 It is not supported to call this function with a non-NULL ANSP2
982 but a NULL ANSCP. Put another way, you can call send_vc with a
983 single unmodifiable buffer or two modifiable buffers, but no other
984 combination is supported.
986 It is the caller's responsibility to free the malloc allocated
987 buffers by detecting that the pointers have changed from their
988 original values i.e. *ANSCP or *ANSP2 has changed.
990 If an answer is truncated because of UDP datagram DNS limits then
991 *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
992 the caller to retry with TCP. The value *GOTSOMEWHERE is set to 1
993 if any progress was made reading a response from the nameserver and
994 is used by the caller to distinguish between ECONNREFUSED and
995 ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
997 If errors are encountered then *TERRNO is set to an appropriate
998 errno value and a zero result is returned for a recoverable error,
999 and a less-than zero result is returned for a non-recoverable error.
1001 If no errors are encountered then *TERRNO is left unmodified and
1002 a the length of the first response in bytes is returned. */
1003 static int
1004 send_dg(res_state statp,
1005 const u_char *buf, int buflen, const u_char *buf2, int buflen2,
1006 u_char **ansp, int *anssizp,
1007 int *terrno, int ns, int *v_circuit, int *gotsomewhere, u_char **anscp,
1008 u_char **ansp2, int *anssizp2, int *resplen2, int *ansp2_malloced)
1010 const HEADER *hp = (HEADER *) buf;
1011 const HEADER *hp2 = (HEADER *) buf2;
1012 struct timespec now, timeout, finish;
1013 struct pollfd pfd[1];
1014 int ptimeout;
1015 struct sockaddr_in6 from;
1016 int resplen = 0;
1017 int n;
1020 * Compute time for the total operation.
1022 int seconds = (statp->retrans << ns);
1023 if (ns > 0)
1024 seconds /= statp->nscount;
1025 if (seconds <= 0)
1026 seconds = 1;
1027 bool single_request_reopen = (statp->options & RES_SNGLKUPREOP) != 0;
1028 bool single_request = (((statp->options & RES_SNGLKUP) != 0)
1029 | single_request_reopen);
1030 int save_gotsomewhere = *gotsomewhere;
1032 int retval;
1033 retry_reopen:
1034 retval = reopen (statp, terrno, ns);
1035 if (retval <= 0)
1037 if (resplen2 != NULL)
1038 *resplen2 = 0;
1039 return retval;
1041 retry:
1042 evNowTime(&now);
1043 evConsTime(&timeout, seconds, 0);
1044 evAddTime(&finish, &now, &timeout);
1045 int need_recompute = 0;
1046 int nwritten = 0;
1047 int recvresp1 = 0;
1048 /* Skip the second response if there is no second query.
1049 To do that we mark the second response as received. */
1050 int recvresp2 = buf2 == NULL;
1051 pfd[0].fd = EXT(statp).nssocks[ns];
1052 pfd[0].events = POLLOUT;
1053 wait:
1054 if (need_recompute) {
1055 recompute_resend:
1056 evNowTime(&now);
1057 if (evCmpTime(finish, now) <= 0) {
1058 poll_err_out:
1059 Perror(statp, stderr, "poll", errno);
1060 return close_and_return_error (statp, resplen2);
1062 evSubTime(&timeout, &finish, &now);
1063 need_recompute = 0;
1065 /* Convert struct timespec in milliseconds. */
1066 ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
1068 n = 0;
1069 if (nwritten == 0)
1070 n = __poll (pfd, 1, 0);
1071 if (__glibc_unlikely (n == 0)) {
1072 n = __poll (pfd, 1, ptimeout);
1073 need_recompute = 1;
1075 if (n == 0) {
1076 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
1077 if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
1079 /* There are quite a few broken name servers out
1080 there which don't handle two outstanding
1081 requests from the same source. There are also
1082 broken firewall settings. If we time out after
1083 having received one answer switch to the mode
1084 where we send the second request only once we
1085 have received the first answer. */
1086 if (!single_request)
1088 statp->options |= RES_SNGLKUP;
1089 single_request = true;
1090 *gotsomewhere = save_gotsomewhere;
1091 goto retry;
1093 else if (!single_request_reopen)
1095 statp->options |= RES_SNGLKUPREOP;
1096 single_request_reopen = true;
1097 *gotsomewhere = save_gotsomewhere;
1098 __res_iclose (statp, false);
1099 goto retry_reopen;
1102 *resplen2 = 1;
1103 return resplen;
1106 *gotsomewhere = 1;
1107 if (resplen2 != NULL)
1108 *resplen2 = 0;
1109 return 0;
1111 if (n < 0) {
1112 if (errno == EINTR)
1113 goto recompute_resend;
1115 goto poll_err_out;
1117 __set_errno (0);
1118 if (pfd[0].revents & POLLOUT) {
1119 #ifndef __ASSUME_SENDMMSG
1120 static int have_sendmmsg;
1121 #else
1122 # define have_sendmmsg 1
1123 #endif
1124 if (have_sendmmsg >= 0 && nwritten == 0 && buf2 != NULL
1125 && !single_request)
1127 struct iovec iov[2];
1128 struct mmsghdr reqs[2];
1129 reqs[0].msg_hdr.msg_name = NULL;
1130 reqs[0].msg_hdr.msg_namelen = 0;
1131 reqs[0].msg_hdr.msg_iov = &iov[0];
1132 reqs[0].msg_hdr.msg_iovlen = 1;
1133 iov[0].iov_base = (void *) buf;
1134 iov[0].iov_len = buflen;
1135 reqs[0].msg_hdr.msg_control = NULL;
1136 reqs[0].msg_hdr.msg_controllen = 0;
1138 reqs[1].msg_hdr.msg_name = NULL;
1139 reqs[1].msg_hdr.msg_namelen = 0;
1140 reqs[1].msg_hdr.msg_iov = &iov[1];
1141 reqs[1].msg_hdr.msg_iovlen = 1;
1142 iov[1].iov_base = (void *) buf2;
1143 iov[1].iov_len = buflen2;
1144 reqs[1].msg_hdr.msg_control = NULL;
1145 reqs[1].msg_hdr.msg_controllen = 0;
1147 int ndg = __sendmmsg (pfd[0].fd, reqs, 2, MSG_NOSIGNAL);
1148 if (__glibc_likely (ndg == 2))
1150 if (reqs[0].msg_len != buflen
1151 || reqs[1].msg_len != buflen2)
1152 goto fail_sendmmsg;
1154 pfd[0].events = POLLIN;
1155 nwritten += 2;
1157 else if (ndg == 1 && reqs[0].msg_len == buflen)
1158 goto just_one;
1159 else if (ndg < 0 && (errno == EINTR || errno == EAGAIN))
1160 goto recompute_resend;
1161 else
1163 #ifndef __ASSUME_SENDMMSG
1164 if (__glibc_unlikely (have_sendmmsg == 0))
1166 if (ndg < 0 && errno == ENOSYS)
1168 have_sendmmsg = -1;
1169 goto try_send;
1171 have_sendmmsg = 1;
1173 #endif
1175 fail_sendmmsg:
1176 Perror(statp, stderr, "sendmmsg", errno);
1177 return close_and_return_error (statp, resplen2);
1180 else
1182 ssize_t sr;
1183 #ifndef __ASSUME_SENDMMSG
1184 try_send:
1185 #endif
1186 if (nwritten != 0)
1187 sr = send (pfd[0].fd, buf2, buflen2, MSG_NOSIGNAL);
1188 else
1189 sr = send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL);
1191 if (sr != (nwritten != 0 ? buflen2 : buflen)) {
1192 if (errno == EINTR || errno == EAGAIN)
1193 goto recompute_resend;
1194 Perror(statp, stderr, "send", errno);
1195 return close_and_return_error (statp, resplen2);
1197 just_one:
1198 if (nwritten != 0 || buf2 == NULL || single_request)
1199 pfd[0].events = POLLIN;
1200 else
1201 pfd[0].events = POLLIN | POLLOUT;
1202 ++nwritten;
1204 goto wait;
1205 } else if (pfd[0].revents & POLLIN) {
1206 int *thisanssizp;
1207 u_char **thisansp;
1208 int *thisresplenp;
1210 if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
1211 /* We have not received any responses
1212 yet or we only have one response to
1213 receive. */
1214 thisanssizp = anssizp;
1215 thisansp = anscp ?: ansp;
1216 assert (anscp != NULL || ansp2 == NULL);
1217 thisresplenp = &resplen;
1218 } else {
1219 thisanssizp = anssizp2;
1220 thisansp = ansp2;
1221 thisresplenp = resplen2;
1224 if (*thisanssizp < MAXPACKET
1225 /* If the current buffer is not the the static
1226 user-supplied buffer then we can reallocate
1227 it. */
1228 && (thisansp != NULL && thisansp != ansp)
1229 #ifdef FIONREAD
1230 /* Is the size too small? */
1231 && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
1232 || *thisanssizp < *thisresplenp)
1233 #endif
1235 /* Always allocate MAXPACKET, callers expect
1236 this specific size. */
1237 u_char *newp = malloc (MAXPACKET);
1238 if (newp != NULL) {
1239 *thisanssizp = MAXPACKET;
1240 *thisansp = newp;
1241 if (thisansp == ansp2)
1242 *ansp2_malloced = 1;
1245 /* We could end up with truncation if anscp was NULL
1246 (not allowed to change caller's buffer) and the
1247 response buffer size is too small. This isn't a
1248 reliable way to detect truncation because the ioctl
1249 may be an inaccurate report of the UDP message size.
1250 Therefore we use this only to issue debug output.
1251 To do truncation accurately with UDP we need
1252 MSG_TRUNC which is only available on Linux. We
1253 can abstract out the Linux-specific feature in the
1254 future to detect truncation. */
1255 if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
1256 Dprint(statp->options & RES_DEBUG,
1257 (stdout, ";; response may be truncated (UDP)\n")
1261 HEADER *anhp = (HEADER *) *thisansp;
1262 socklen_t fromlen = sizeof(struct sockaddr_in6);
1263 assert (sizeof(from) <= fromlen);
1264 *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
1265 *thisanssizp, 0,
1266 (struct sockaddr *)&from, &fromlen);
1267 if (__glibc_unlikely (*thisresplenp <= 0)) {
1268 if (errno == EINTR || errno == EAGAIN) {
1269 need_recompute = 1;
1270 goto wait;
1272 Perror(statp, stderr, "recvfrom", errno);
1273 return close_and_return_error (statp, resplen2);
1275 *gotsomewhere = 1;
1276 if (__glibc_unlikely (*thisresplenp < HFIXEDSZ)) {
1278 * Undersized message.
1280 Dprint(statp->options & RES_DEBUG,
1281 (stdout, ";; undersized: %d\n",
1282 *thisresplenp));
1283 *terrno = EMSGSIZE;
1284 return close_and_return_error (statp, resplen2);
1286 if ((recvresp1 || hp->id != anhp->id)
1287 && (recvresp2 || hp2->id != anhp->id)) {
1289 * response from old query, ignore it.
1290 * XXX - potential security hazard could
1291 * be detected here.
1293 DprintQ((statp->options & RES_DEBUG) ||
1294 (statp->pfcode & RES_PRF_REPLY),
1295 (stdout, ";; old answer:\n"),
1296 *thisansp,
1297 (*thisresplenp > *thisanssizp)
1298 ? *thisanssizp : *thisresplenp);
1299 goto wait;
1301 if (!(statp->options & RES_INSECURE1) &&
1302 !res_ourserver_p(statp, &from)) {
1304 * response from wrong server? ignore it.
1305 * XXX - potential security hazard could
1306 * be detected here.
1308 DprintQ((statp->options & RES_DEBUG) ||
1309 (statp->pfcode & RES_PRF_REPLY),
1310 (stdout, ";; not our server:\n"),
1311 *thisansp,
1312 (*thisresplenp > *thisanssizp)
1313 ? *thisanssizp : *thisresplenp);
1314 goto wait;
1316 #ifdef RES_USE_EDNS0
1317 if (anhp->rcode == FORMERR
1318 && (statp->options & RES_USE_EDNS0) != 0U) {
1320 * Do not retry if the server does not understand
1321 * EDNS0. The case has to be captured here, as
1322 * FORMERR packet do not carry query section, hence
1323 * res_queriesmatch() returns 0.
1325 DprintQ(statp->options & RES_DEBUG,
1326 (stdout,
1327 "server rejected query with EDNS0:\n"),
1328 *thisansp,
1329 (*thisresplenp > *thisanssizp)
1330 ? *thisanssizp : *thisresplenp);
1331 /* record the error */
1332 statp->_flags |= RES_F_EDNS0ERR;
1333 return close_and_return_error (statp, resplen2);
1335 #endif
1336 if (!(statp->options & RES_INSECURE2)
1337 && (recvresp1 || !res_queriesmatch(buf, buf + buflen,
1338 *thisansp,
1339 *thisansp
1340 + *thisanssizp))
1341 && (recvresp2 || !res_queriesmatch(buf2, buf2 + buflen2,
1342 *thisansp,
1343 *thisansp
1344 + *thisanssizp))) {
1346 * response contains wrong query? ignore it.
1347 * XXX - potential security hazard could
1348 * be detected here.
1350 DprintQ((statp->options & RES_DEBUG) ||
1351 (statp->pfcode & RES_PRF_REPLY),
1352 (stdout, ";; wrong query name:\n"),
1353 *thisansp,
1354 (*thisresplenp > *thisanssizp)
1355 ? *thisanssizp : *thisresplenp);
1356 goto wait;
1358 if (anhp->rcode == SERVFAIL ||
1359 anhp->rcode == NOTIMP ||
1360 anhp->rcode == REFUSED) {
1361 DprintQ(statp->options & RES_DEBUG,
1362 (stdout, "server rejected query:\n"),
1363 *thisansp,
1364 (*thisresplenp > *thisanssizp)
1365 ? *thisanssizp : *thisresplenp);
1367 next_ns:
1368 if (recvresp1 || (buf2 != NULL && recvresp2)) {
1369 *resplen2 = 0;
1370 return resplen;
1372 if (buf2 != NULL)
1374 /* No data from the first reply. */
1375 resplen = 0;
1376 /* We are waiting for a possible second reply. */
1377 if (hp->id == anhp->id)
1378 recvresp1 = 1;
1379 else
1380 recvresp2 = 1;
1382 goto wait;
1385 /* don't retry if called from dig */
1386 if (!statp->pfcode)
1387 return close_and_return_error (statp, resplen2);
1388 __res_iclose(statp, false);
1390 if (anhp->rcode == NOERROR && anhp->ancount == 0
1391 && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) {
1392 DprintQ(statp->options & RES_DEBUG,
1393 (stdout, "referred query:\n"),
1394 *thisansp,
1395 (*thisresplenp > *thisanssizp)
1396 ? *thisanssizp : *thisresplenp);
1397 goto next_ns;
1399 if (!(statp->options & RES_IGNTC) && anhp->tc) {
1401 * To get the rest of answer,
1402 * use TCP with same server.
1404 Dprint(statp->options & RES_DEBUG,
1405 (stdout, ";; truncated answer\n"));
1406 *v_circuit = 1;
1407 __res_iclose(statp, false);
1408 // XXX if we have received one reply we could
1409 // XXX use it and not repeat it over TCP...
1410 if (resplen2 != NULL)
1411 *resplen2 = 0;
1412 return (1);
1414 /* Mark which reply we received. */
1415 if (recvresp1 == 0 && hp->id == anhp->id)
1416 recvresp1 = 1;
1417 else
1418 recvresp2 = 1;
1419 /* Repeat waiting if we have a second answer to arrive. */
1420 if ((recvresp1 & recvresp2) == 0) {
1421 if (single_request) {
1422 pfd[0].events = POLLOUT;
1423 if (single_request_reopen) {
1424 __res_iclose (statp, false);
1425 retval = reopen (statp, terrno, ns);
1426 if (retval <= 0)
1428 if (resplen2 != NULL)
1429 *resplen2 = 0;
1430 return retval;
1432 pfd[0].fd = EXT(statp).nssocks[ns];
1435 goto wait;
1437 /* All is well. We have received both responses (if
1438 two responses were requested). */
1439 return (resplen);
1440 } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL))
1441 /* Something went wrong. We can stop trying. */
1442 return close_and_return_error (statp, resplen2);
1443 else {
1444 /* poll should not have returned > 0 in this case. */
1445 abort ();
1449 #ifdef DEBUG
1450 static void
1451 Aerror(const res_state statp, FILE *file, const char *string, int error,
1452 const struct sockaddr *address)
1454 int save = errno;
1456 if ((statp->options & RES_DEBUG) != 0) {
1457 char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
1459 fprintf(file, "res_send: %s ([%s].%u): %s\n",
1460 string,
1461 (address->sa_family == AF_INET
1462 ? inet_ntop(address->sa_family,
1463 &((const struct sockaddr_in *) address)->sin_addr,
1464 tmp, sizeof tmp)
1465 : inet_ntop(address->sa_family,
1466 &((const struct sockaddr_in6 *) address)->sin6_addr,
1467 tmp, sizeof tmp)),
1468 (address->sa_family == AF_INET
1469 ? ntohs(((struct sockaddr_in *) address)->sin_port)
1470 : address->sa_family == AF_INET6
1471 ? ntohs(((struct sockaddr_in6 *) address)->sin6_port)
1472 : 0),
1473 strerror(error));
1475 __set_errno (save);
1478 static void
1479 Perror(const res_state statp, FILE *file, const char *string, int error) {
1480 int save = errno;
1482 if ((statp->options & RES_DEBUG) != 0)
1483 fprintf(file, "res_send: %s: %s\n",
1484 string, strerror(error));
1485 __set_errno (save);
1487 #endif
1489 static int
1490 sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
1491 if (a1->sin6_family == a2->sin6_family) {
1492 if (a1->sin6_family == AF_INET)
1493 return ((((struct sockaddr_in *)a1)->sin_port ==
1494 ((struct sockaddr_in *)a2)->sin_port) &&
1495 (((struct sockaddr_in *)a1)->sin_addr.s_addr ==
1496 ((struct sockaddr_in *)a2)->sin_addr.s_addr));
1497 else
1498 return ((a1->sin6_port == a2->sin6_port) &&
1499 !memcmp(&a1->sin6_addr, &a2->sin6_addr,
1500 sizeof (struct in6_addr)));
1502 if (a1->sin6_family == AF_INET) {
1503 struct sockaddr_in6 *sap = a1;
1504 a1 = a2;
1505 a2 = sap;
1506 } /* assumes that AF_INET and AF_INET6 are the only possibilities */
1507 return ((a1->sin6_port == ((struct sockaddr_in *)a2)->sin_port) &&
1508 IN6_IS_ADDR_V4MAPPED(&a1->sin6_addr) &&
1509 (a1->sin6_addr.s6_addr32[3] ==
1510 ((struct sockaddr_in *)a2)->sin_addr.s_addr));