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