2 * Copyright (c) 1985, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
31 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
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.
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
51 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
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.
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
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 */
73 * Send query to name server and wait for reply.
77 #include <sys/types.h>
78 #include <sys/param.h>
80 #include <sys/socket.h>
84 #include <netinet/in.h>
85 #include <arpa/nameser.h>
86 #include <arpa/inet.h>
87 #include <sys/ioctl.h>
100 #define MAXPACKET PACKETSZ
102 #define MAXPACKET 65536
106 /* From ev_streams.c. */
109 __attribute ((always_inline
))
110 evConsIovec(void *buf
, size_t cnt
, struct iovec
*vec
) {
111 memset(vec
, 0xf5, sizeof (*vec
));
116 /* From ev_timers.c. */
118 #define BILLION 1000000000
121 evConsTime(struct timespec
*res
, time_t sec
, long nsec
) {
127 evAddTime(struct timespec
*res
, const struct timespec
*addend1
,
128 const struct timespec
*addend2
) {
129 res
->tv_sec
= addend1
->tv_sec
+ addend2
->tv_sec
;
130 res
->tv_nsec
= addend1
->tv_nsec
+ addend2
->tv_nsec
;
131 if (res
->tv_nsec
>= BILLION
) {
133 res
->tv_nsec
-= BILLION
;
138 evSubTime(struct timespec
*res
, const struct timespec
*minuend
,
139 const struct timespec
*subtrahend
) {
140 res
->tv_sec
= minuend
->tv_sec
- subtrahend
->tv_sec
;
141 if (minuend
->tv_nsec
>= subtrahend
->tv_nsec
)
142 res
->tv_nsec
= minuend
->tv_nsec
- subtrahend
->tv_nsec
;
144 res
->tv_nsec
= (BILLION
145 - subtrahend
->tv_nsec
+ minuend
->tv_nsec
);
151 evCmpTime(struct timespec a
, struct timespec b
) {
152 long x
= a
.tv_sec
- b
.tv_sec
;
155 x
= a
.tv_nsec
- b
.tv_nsec
;
156 return (x
< 0L ? (-1) : x
> 0L ? (1) : (0));
160 evNowTime(struct timespec
*res
) {
163 if (gettimeofday(&now
, NULL
) < 0)
164 evConsTime(res
, 0, 0);
166 TIMEVAL_TO_TIMESPEC (&now
, res
);
170 /* Options. Leave them on. */
172 #include "res_debug.h"
174 #define EXT(res) ((res)->_u._ext)
178 static int send_vc(res_state
, const u_char
*, int,
180 u_char
**, int *, int *, int, u_char
**,
181 u_char
**, int *, int *);
182 static int send_dg(res_state
, const u_char
*, int,
184 u_char
**, int *, int *, int,
185 int *, int *, u_char
**,
186 u_char
**, int *, int *);
188 static void Aerror(const res_state
, FILE *, const char *, int,
189 const struct sockaddr
*);
190 static void Perror(const res_state
, FILE *, const char *, int);
192 static int sock_eq(struct sockaddr_in6
*, struct sockaddr_in6
*);
196 static void convaddr4to6(struct sockaddr_in6
*sa
);
201 * res_isourserver(ina)
202 * looks up "ina" in _res.ns_addr_list[]
207 * paul vixie, 29may94
210 res_ourserver_p(const res_state statp
, const struct sockaddr_in6
*inp
)
214 if (inp
->sin6_family
== AF_INET
) {
215 struct sockaddr_in
*in4p
= (struct sockaddr_in
*) inp
;
216 in_port_t port
= in4p
->sin_port
;
217 in_addr_t addr
= in4p
->sin_addr
.s_addr
;
219 for (ns
= 0; ns
< MAXNS
; ns
++) {
220 const struct sockaddr_in
*srv
=
221 (struct sockaddr_in
*)EXT(statp
).nsaddrs
[ns
];
223 if ((srv
!= NULL
) && (srv
->sin_family
== AF_INET
) &&
224 (srv
->sin_port
== port
) &&
225 (srv
->sin_addr
.s_addr
== INADDR_ANY
||
226 srv
->sin_addr
.s_addr
== addr
))
229 } else if (inp
->sin6_family
== AF_INET6
) {
230 for (ns
= 0; ns
< MAXNS
; ns
++) {
231 const struct sockaddr_in6
*srv
= EXT(statp
).nsaddrs
[ns
];
232 if ((srv
!= NULL
) && (srv
->sin6_family
== AF_INET6
) &&
233 (srv
->sin6_port
== inp
->sin6_port
) &&
234 !(memcmp(&srv
->sin6_addr
, &in6addr_any
,
235 sizeof (struct in6_addr
)) &&
236 memcmp(&srv
->sin6_addr
, &inp
->sin6_addr
,
237 sizeof (struct in6_addr
))))
245 * res_nameinquery(name, type, class, buf, eom)
246 * look for (name,type,class) in the query section of packet (buf,eom)
248 * buf + HFIXEDSZ <= eom
254 * paul vixie, 29may94
257 res_nameinquery(const char *name
, int type
, int class,
258 const u_char
*buf
, const u_char
*eom
)
260 const u_char
*cp
= buf
+ HFIXEDSZ
;
261 int qdcount
= ntohs(((HEADER
*)buf
)->qdcount
);
263 while (qdcount
-- > 0) {
264 char tname
[MAXDNAME
+1];
265 int n
, ttype
, tclass
;
267 n
= dn_expand(buf
, eom
, cp
, tname
, sizeof tname
);
271 if (cp
+ 2 * INT16SZ
> eom
)
274 NS_GET16(tclass
, cp
);
275 if (ttype
== type
&& tclass
== class &&
276 ns_samename(tname
, name
) == 1)
281 libresolv_hidden_def (res_nameinquery
)
284 * res_queriesmatch(buf1, eom1, buf2, eom2)
285 * is there a 1:1 mapping of (name,type,class)
286 * in (buf1,eom1) and (buf2,eom2)?
289 * 0 : not a 1:1 mapping
290 * >0 : is a 1:1 mapping
292 * paul vixie, 29may94
295 res_queriesmatch(const u_char
*buf1
, const u_char
*eom1
,
296 const u_char
*buf2
, const u_char
*eom2
)
298 if (buf1
+ HFIXEDSZ
> eom1
|| buf2
+ HFIXEDSZ
> eom2
)
302 * Only header section present in replies to
303 * dynamic update packets.
305 if ((((HEADER
*)buf1
)->opcode
== ns_o_update
) &&
306 (((HEADER
*)buf2
)->opcode
== ns_o_update
))
309 /* Note that we initially do not convert QDCOUNT to the host byte
310 order. We can compare it with the second buffer's QDCOUNT
311 value without doing this. */
312 int qdcount
= ((HEADER
*)buf1
)->qdcount
;
313 if (qdcount
!= ((HEADER
*)buf2
)->qdcount
)
316 qdcount
= htons (qdcount
);
317 const u_char
*cp
= buf1
+ HFIXEDSZ
;
319 while (qdcount
-- > 0) {
320 char tname
[MAXDNAME
+1];
321 int n
, ttype
, tclass
;
323 n
= dn_expand(buf1
, eom1
, cp
, tname
, sizeof tname
);
327 if (cp
+ 2 * INT16SZ
> eom1
)
330 NS_GET16(tclass
, cp
);
331 if (!res_nameinquery(tname
, ttype
, tclass
, buf2
, eom2
))
336 libresolv_hidden_def (res_queriesmatch
)
339 __libc_res_nsend(res_state statp
, const u_char
*buf
, int buflen
,
340 const u_char
*buf2
, int buflen2
,
341 u_char
*ans
, int anssiz
, u_char
**ansp
, u_char
**ansp2
,
342 int *nansp2
, int *resplen2
)
344 int gotsomewhere
, terrno
, try, v_circuit
, resplen
, ns
, n
;
346 if (statp
->nscount
== 0) {
351 if (anssiz
< (buf2
== NULL
? 1 : 2) * HFIXEDSZ
) {
352 __set_errno (EINVAL
);
357 if (__builtin_expect (statp
->qhook
|| statp
->rhook
, 0)) {
358 if (anssiz
< MAXPACKET
&& ansp
) {
359 u_char
*buf
= malloc (MAXPACKET
);
362 memcpy (buf
, ans
, HFIXEDSZ
);
370 DprintQ((statp
->options
& RES_DEBUG
) || (statp
->pfcode
& RES_PRF_QUERY
),
371 (stdout
, ";; res_send()\n"), buf
, buflen
);
372 v_circuit
= ((statp
->options
& RES_USEVC
)
374 || buflen2
> PACKETSZ
);
379 * If the ns_addr_list in the resolver context has changed, then
380 * invalidate our cached copy and the associated timing data.
382 if (EXT(statp
).nsinit
) {
385 if (EXT(statp
).nscount
!= statp
->nscount
)
388 for (ns
= 0; ns
< MAXNS
; ns
++) {
389 unsigned int map
= EXT(statp
).nsmap
[ns
];
391 && !sock_eq((struct sockaddr_in6
*)
392 &statp
->nsaddr_list
[map
],
393 EXT(statp
).nsaddrs
[ns
]))
400 __res_iclose(statp
, false);
404 * Maybe initialize our private copy of the ns_addr_list.
406 if (EXT(statp
).nsinit
== 0) {
407 unsigned char map
[MAXNS
];
409 memset (map
, MAXNS
, sizeof (map
));
410 for (n
= 0; n
< MAXNS
; n
++) {
411 ns
= EXT(statp
).nsmap
[n
];
412 if (ns
< statp
->nscount
)
414 else if (ns
< MAXNS
) {
415 free(EXT(statp
).nsaddrs
[n
]);
416 EXT(statp
).nsaddrs
[n
] = NULL
;
417 EXT(statp
).nsmap
[n
] = MAXNS
;
421 if (statp
->nscount
> EXT(statp
).nscount
)
422 for (n
= EXT(statp
).nscount
, ns
= 0;
423 n
< statp
->nscount
; n
++) {
425 && EXT(statp
).nsmap
[ns
] != MAXNS
)
429 EXT(statp
).nsmap
[ns
] = n
;
432 EXT(statp
).nscount
= n
;
433 for (ns
= 0; ns
< EXT(statp
).nscount
; ns
++) {
435 if (EXT(statp
).nsaddrs
[n
] == NULL
)
436 EXT(statp
).nsaddrs
[n
] =
437 malloc(sizeof (struct sockaddr_in6
));
438 if (EXT(statp
).nsaddrs
[n
] != NULL
) {
439 memset (mempcpy(EXT(statp
).nsaddrs
[n
],
440 &statp
->nsaddr_list
[ns
],
441 sizeof (struct sockaddr_in
)),
443 sizeof (struct sockaddr_in6
)
444 - sizeof (struct sockaddr_in
));
445 EXT(statp
).nssocks
[n
] = -1;
449 EXT(statp
).nsinit
= 1;
453 * Some resolvers want to even out the load on their nameservers.
454 * Note that RES_BLAST overrides RES_ROTATE.
456 if (__builtin_expect ((statp
->options
& RES_ROTATE
) != 0, 0) &&
457 (statp
->options
& RES_BLAST
) == 0) {
458 struct sockaddr_in6
*ina
;
462 while (n
< MAXNS
&& EXT(statp
).nsmap
[n
] == MAXNS
)
465 ina
= EXT(statp
).nsaddrs
[n
];
466 map
= EXT(statp
).nsmap
[n
];
470 && EXT(statp
).nsmap
[ns
] == MAXNS
)
474 EXT(statp
).nsaddrs
[n
] = EXT(statp
).nsaddrs
[ns
];
475 EXT(statp
).nsmap
[n
] = EXT(statp
).nsmap
[ns
];
478 EXT(statp
).nsaddrs
[n
] = ina
;
479 EXT(statp
).nsmap
[n
] = map
;
484 * Send request, RETRY times, or until successful.
486 for (try = 0; try < statp
->retry
; try++) {
487 for (ns
= 0; ns
< MAXNS
; ns
++)
489 struct sockaddr_in6
*nsap
= EXT(statp
).nsaddrs
[ns
];
495 if (__builtin_expect (statp
->qhook
!= NULL
, 0)) {
496 int done
= 0, loops
= 0;
501 struct sockaddr_in
*nsap4
;
502 nsap4
= (struct sockaddr_in
*) nsap
;
503 act
= (*statp
->qhook
)(&nsap4
, &buf
, &buflen
,
504 ans
, anssiz
, &resplen
);
505 nsap
= (struct sockaddr_in6
*) nsap4
;
511 __res_iclose(statp
, false);
516 /* give the hook another try */
517 if (++loops
< 42) /*doug adams*/
532 Dprint(statp
->options
& RES_DEBUG
,
533 (stdout
, ";; Querying server (# %d) address = %s\n",
534 ns
+ 1, inet_ntop(AF_INET6
, &nsap
->sin6_addr
,
535 tmpbuf
, sizeof (tmpbuf
))));
537 if (__builtin_expect (v_circuit
, 0)) {
538 /* Use VC; at most one attempt per server. */
540 n
= send_vc(statp
, buf
, buflen
, buf2
, buflen2
,
541 &ans
, &anssiz
, &terrno
,
542 ns
, ansp
, ansp2
, nansp2
, resplen2
);
549 n
= send_dg(statp
, buf
, buflen
, buf2
, buflen2
,
550 &ans
, &anssiz
, &terrno
,
551 ns
, &v_circuit
, &gotsomewhere
, ansp
,
552 ansp2
, nansp2
, resplen2
);
558 // XXX Check whether both requests failed or
559 // XXX whether one has been answered successfully
565 Dprint((statp
->options
& RES_DEBUG
) ||
566 ((statp
->pfcode
& RES_PRF_REPLY
) &&
567 (statp
->pfcode
& RES_PRF_HEAD1
)),
568 (stdout
, ";; got answer:\n"));
570 DprintQ((statp
->options
& RES_DEBUG
) ||
571 (statp
->pfcode
& RES_PRF_REPLY
),
573 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
575 DprintQ((statp
->options
& RES_DEBUG
) ||
576 (statp
->pfcode
& RES_PRF_REPLY
),
578 *ansp2
, (*resplen2
> *nansp2
) ? *nansp2
: *resplen2
);
581 * If we have temporarily opened a virtual circuit,
582 * or if we haven't been asked to keep a socket open,
585 if ((v_circuit
&& (statp
->options
& RES_USEVC
) == 0) ||
586 (statp
->options
& RES_STAYOPEN
) == 0) {
587 __res_iclose(statp
, false);
590 if (__builtin_expect (statp
->rhook
, 0)) {
591 int done
= 0, loops
= 0;
596 act
= (*statp
->rhook
)((struct sockaddr_in
*)
598 ans
, anssiz
, &resplen
);
605 __res_iclose(statp
, false);
608 /* give the hook another try */
609 if (++loops
< 42) /*doug adams*/
625 __res_iclose(statp
, false);
628 __set_errno (ECONNREFUSED
); /* no nameservers found */
630 __set_errno (ETIMEDOUT
); /* no answer obtained */
632 __set_errno (terrno
);
637 res_nsend(res_state statp
,
638 const u_char
*buf
, int buflen
, u_char
*ans
, int anssiz
)
640 return __libc_res_nsend(statp
, buf
, buflen
, NULL
, 0, ans
, anssiz
,
641 NULL
, NULL
, NULL
, NULL
);
643 libresolv_hidden_def (res_nsend
)
648 send_vc(res_state statp
,
649 const u_char
*buf
, int buflen
, const u_char
*buf2
, int buflen2
,
650 u_char
**ansp
, int *anssizp
,
651 int *terrno
, int ns
, u_char
**anscp
, u_char
**ansp2
, int *anssizp2
,
654 const HEADER
*hp
= (HEADER
*) buf
;
655 const HEADER
*hp2
= (HEADER
*) buf2
;
657 int orig_anssizp
= *anssizp
;
659 // int anssiz = *anssizp;
660 HEADER
*anhp
= (HEADER
*) ans
;
661 struct sockaddr_in6
*nsap
= EXT(statp
).nsaddrs
[ns
];
662 int truncating
, connreset
, resplen
, n
;
668 if (resplen2
!= NULL
)
674 /* Are we still talking to whom we want to talk to? */
675 if (statp
->_vcsock
>= 0 && (statp
->_flags
& RES_F_VC
) != 0) {
676 struct sockaddr_in6 peer
;
677 socklen_t size
= sizeof peer
;
679 if (getpeername(statp
->_vcsock
,
680 (struct sockaddr
*)&peer
, &size
) < 0 ||
681 !sock_eq(&peer
, nsap
)) {
682 __res_iclose(statp
, false);
683 statp
->_flags
&= ~RES_F_VC
;
687 if (statp
->_vcsock
< 0 || (statp
->_flags
& RES_F_VC
) == 0) {
688 if (statp
->_vcsock
>= 0)
689 __res_iclose(statp
, false);
691 statp
->_vcsock
= socket(nsap
->sin6_family
, SOCK_STREAM
, 0);
692 if (statp
->_vcsock
< 0) {
694 Perror(statp
, stderr
, "socket(vc)", errno
);
698 if (connect(statp
->_vcsock
, (struct sockaddr
*)nsap
,
699 nsap
->sin6_family
== AF_INET
700 ? sizeof (struct sockaddr_in
)
701 : sizeof (struct sockaddr_in6
)) < 0) {
703 Aerror(statp
, stderr
, "connect/vc", errno
,
704 (struct sockaddr
*) nsap
);
705 __res_iclose(statp
, false);
708 statp
->_flags
|= RES_F_VC
;
712 * Send length & message
714 len
= htons ((u_short
) buflen
);
715 evConsIovec(&len
, INT16SZ
, &iov
[0]);
716 evConsIovec((void*)buf
, buflen
, &iov
[1]);
718 ssize_t explen
= INT16SZ
+ buflen
;
720 len2
= htons ((u_short
) buflen2
);
721 evConsIovec(&len2
, INT16SZ
, &iov
[2]);
722 evConsIovec((void*)buf2
, buflen2
, &iov
[3]);
724 explen
+= INT16SZ
+ buflen2
;
726 if (TEMP_FAILURE_RETRY (writev(statp
->_vcsock
, iov
, niov
)) != explen
) {
728 Perror(statp
, stderr
, "write failed", errno
);
729 __res_iclose(statp
, false);
733 * Receive length & response
736 int recvresp2
= buf2
== NULL
;
739 cp
= (u_char
*)&rlen16
;
740 len
= sizeof(rlen16
);
741 while ((n
= TEMP_FAILURE_RETRY (read(statp
->_vcsock
, cp
,
749 Perror(statp
, stderr
, "read failed", errno
);
750 __res_iclose(statp
, false);
752 * A long running process might get its TCP
753 * connection reset if the remote server was
754 * restarted. Requery the server instead of
755 * trying a new one. When there is only one
756 * server, this means that a query might work
757 * instead of failing. We only allow one reset
758 * per query to prevent looping.
760 if (*terrno
== ECONNRESET
&& !connreset
) {
766 int rlen
= ntohs (rlen16
);
771 if ((recvresp1
| recvresp2
) == 0 || buf2
== NULL
) {
772 thisanssizp
= anssizp
;
773 thisansp
= anscp
?: ansp
;
774 assert (anscp
!= NULL
|| ansp2
== NULL
);
775 thisresplenp
= &resplen
;
777 if (*anssizp
!= MAXPACKET
) {
778 /* No buffer allocated for the first
779 reply. We can try to use the rest
780 of the user-provided buffer. */
781 #ifdef _STRING_ARCH_unaligned
782 *anssizp2
= orig_anssizp
- resplen
;
783 *ansp2
= *ansp
+ resplen
;
786 = ((resplen
+ __alignof__ (HEADER
) - 1)
787 & ~(__alignof__ (HEADER
) - 1));
788 *anssizp2
= orig_anssizp
- aligned_resplen
;
789 *ansp2
= *ansp
+ aligned_resplen
;
792 /* The first reply did not fit into the
793 user-provided buffer. Maybe the second
795 *anssizp2
= orig_anssizp
;
799 thisanssizp
= anssizp2
;
801 thisresplenp
= resplen2
;
803 anhp
= (HEADER
*) *thisansp
;
805 *thisresplenp
= rlen
;
806 if (rlen
> *thisanssizp
) {
807 /* Yes, we test ANSCP here. If we have two buffers
808 both will be allocatable. */
809 if (__builtin_expect (anscp
!= NULL
, 1)) {
810 u_char
*newp
= malloc (MAXPACKET
);
813 __res_iclose(statp
, false);
816 *thisanssizp
= MAXPACKET
;
818 anhp
= (HEADER
*) newp
;
821 Dprint(statp
->options
& RES_DEBUG
,
822 (stdout
, ";; response truncated\n")
830 if (__builtin_expect (len
< HFIXEDSZ
, 0)) {
832 * Undersized message.
834 Dprint(statp
->options
& RES_DEBUG
,
835 (stdout
, ";; undersized: %d\n", len
));
837 __res_iclose(statp
, false);
842 while (len
!= 0 && (n
= read(statp
->_vcsock
, (char *)cp
, (int)len
)) > 0){
846 if (__builtin_expect (n
<= 0, 0)) {
848 Perror(statp
, stderr
, "read(vc)", errno
);
849 __res_iclose(statp
, false);
852 if (__builtin_expect (truncating
, 0)) {
854 * Flush rest of answer so connection stays in synch.
857 len
= rlen
- *thisanssizp
;
861 n
= read(statp
->_vcsock
, junk
,
862 (len
> sizeof junk
) ? sizeof junk
: len
);
870 * If the calling applicating has bailed out of
871 * a previous call and failed to arrange to have
872 * the circuit closed or the server has got
873 * itself confused, then drop the packet and
874 * wait for the correct one.
876 if ((recvresp1
|| hp
->id
!= anhp
->id
)
877 && (recvresp2
|| hp2
->id
!= anhp
->id
)) {
878 DprintQ((statp
->options
& RES_DEBUG
) ||
879 (statp
->pfcode
& RES_PRF_REPLY
),
880 (stdout
, ";; old answer (unexpected):\n"),
882 (rlen
> *thisanssiz
) ? *thisanssiz
: rlen
);
886 /* Mark which reply we received. */
887 if (recvresp1
== 0 && hp
->id
== anhp
->id
)
891 /* Repeat waiting if we have a second answer to arrive. */
892 if ((recvresp1
& recvresp2
) == 0)
896 * All is well, or the error is fatal. Signal that the
897 * next nameserver ought not be tried.
903 send_dg(res_state statp
,
904 const u_char
*buf
, int buflen
, const u_char
*buf2
, int buflen2
,
905 u_char
**ansp
, int *anssizp
,
906 int *terrno
, int ns
, int *v_circuit
, int *gotsomewhere
, u_char
**anscp
,
907 u_char
**ansp2
, int *anssizp2
, int *resplen2
)
909 const HEADER
*hp
= (HEADER
*) buf
;
910 const HEADER
*hp2
= (HEADER
*) buf2
;
912 int orig_anssizp
= *anssizp
;
913 struct sockaddr_in6
*nsap
= EXT(statp
).nsaddrs
[ns
];
914 struct timespec now
, timeout
, finish
;
915 struct pollfd pfd
[1];
917 struct sockaddr_in6 from
;
918 int resplen
, seconds
, n
;
920 if (EXT(statp
).nssocks
[ns
] == -1) {
921 /* only try IPv6 if IPv6 NS and if not failed before */
922 if ((EXT(statp
).nscount6
> 0) && !statp
->ipv6_unavail
) {
923 EXT(statp
).nssocks
[ns
] =
924 socket(PF_INET6
, SOCK_DGRAM
, 0);
925 if (EXT(statp
).nssocks
[ns
] < 0)
926 statp
->ipv6_unavail
= errno
== EAFNOSUPPORT
;
927 /* If IPv6 socket and nsap is IPv4, make it
929 else if (nsap
->sin6_family
== AF_INET
)
932 if (EXT(statp
).nssocks
[ns
] < 0)
933 EXT(statp
).nssocks
[ns
] = socket(PF_INET
, SOCK_DGRAM
, 0);
934 if (EXT(statp
).nssocks
[ns
] < 0) {
936 Perror(statp
, stderr
, "socket(dg)", errno
);
941 * On a 4.3BSD+ machine (client and server,
942 * actually), sending to a nameserver datagram
943 * port with no nameserver will cause an
944 * ICMP port unreachable message to be returned.
945 * If our datagram socket is "connected" to the
946 * server, we get an ECONNREFUSED error on the next
947 * socket operation, and select returns if the
948 * error message is received. We can thus detect
949 * the absence of a nameserver without timing out.
951 if (connect(EXT(statp
).nssocks
[ns
], (struct sockaddr
*)nsap
,
953 Aerror(statp
, stderr
, "connect(dg)", errno
,
954 (struct sockaddr
*) nsap
);
955 __res_iclose(statp
, false);
958 /* Make socket non-blocking. */
959 int fl
= __fcntl (EXT(statp
).nssocks
[ns
], F_GETFL
);
961 __fcntl (EXT(statp
).nssocks
[ns
], F_SETFL
,
963 Dprint(statp
->options
& RES_DEBUG
,
964 (stdout
, ";; new DG socket\n"))
968 * Compute time for the total operation.
970 seconds
= (statp
->retrans
<< ns
);
972 seconds
/= statp
->nscount
;
976 evConsTime(&timeout
, seconds
, 0);
977 evAddTime(&finish
, &now
, &timeout
);
978 int need_recompute
= 0;
981 int recvresp2
= buf2
== NULL
;
982 pfd
[0].fd
= EXT(statp
).nssocks
[ns
];
983 pfd
[0].events
= POLLOUT
;
984 if (resplen2
!= NULL
)
987 if (need_recompute
) {
990 if (evCmpTime(finish
, now
) <= 0) {
992 Perror(statp
, stderr
, "poll", errno
);
994 __res_iclose(statp
, false);
997 evSubTime(&timeout
, &finish
, &now
);
999 /* Convert struct timespec in milliseconds. */
1000 ptimeout
= timeout
.tv_sec
* 1000 + timeout
.tv_nsec
/ 1000000;
1004 n
= __poll (pfd
, 1, 0);
1005 if (__builtin_expect (n
== 0, 0)) {
1006 n
= __poll (pfd
, 1, ptimeout
);
1010 Dprint(statp
->options
& RES_DEBUG
, (stdout
, ";; timeout\n"));
1011 if (resplen
> 1 && (recvresp1
|| (buf2
!= NULL
&& recvresp2
)))
1022 goto recompute_resend
;
1027 if (pfd
[0].revents
& POLLOUT
) {
1030 sr
= send (pfd
[0].fd
, buf2
, buflen2
, MSG_NOSIGNAL
);
1032 sr
= send (pfd
[0].fd
, buf
, buflen
, MSG_NOSIGNAL
);
1035 if (errno
== EINTR
|| errno
== EAGAIN
)
1036 goto recompute_resend
;
1037 Perror(statp
, stderr
, "send", errno
);
1040 if (nwritten
!= 0 || buf2
== NULL
)
1041 pfd
[0].events
= POLLIN
;
1043 pfd
[0].events
= POLLIN
| POLLOUT
;
1046 } else if (pfd
[0].revents
& POLLIN
) {
1051 if ((recvresp1
| recvresp2
) == 0 || buf2
== NULL
) {
1052 thisanssizp
= anssizp
;
1053 thisansp
= anscp
?: ansp
;
1054 assert (anscp
!= NULL
|| ansp2
== NULL
);
1055 thisresplenp
= &resplen
;
1057 if (*anssizp
!= MAXPACKET
) {
1058 /* No buffer allocated for the first
1059 reply. We can try to use the rest
1060 of the user-provided buffer. */
1061 #ifdef _STRING_ARCH_unaligned
1062 *anssizp2
= orig_anssizp
- resplen
;
1063 *ansp2
= *ansp
+ resplen
;
1066 = ((resplen
+ __alignof__ (HEADER
) - 1)
1067 & ~(__alignof__ (HEADER
) - 1));
1068 *anssizp2
= orig_anssizp
- aligned_resplen
;
1069 *ansp2
= *ansp
+ aligned_resplen
;
1072 /* The first reply did not fit into the
1073 user-provided buffer. Maybe the second
1075 *anssizp2
= orig_anssizp
;
1079 thisanssizp
= anssizp2
;
1081 thisresplenp
= resplen2
;
1084 if (*thisanssizp
< MAXPACKET
1085 /* Yes, we test ANSCP here. If we have two buffers
1086 both will be allocatable. */
1088 && (ioctl (pfd
[0].fd
, FIONREAD
, thisresplenp
) < 0
1089 || *thisanssizp
< *thisresplenp
)) {
1090 u_char
*newp
= malloc (MAXPACKET
);
1092 *anssizp
= MAXPACKET
;
1093 *thisansp
= ans
= newp
;
1096 HEADER
*anhp
= (HEADER
*) *thisansp
;
1097 socklen_t fromlen
= sizeof(struct sockaddr_in6
);
1098 assert (sizeof(from
) <= fromlen
);
1099 *thisresplenp
= recvfrom(pfd
[0].fd
, (char*)*thisansp
,
1101 (struct sockaddr
*)&from
, &fromlen
);
1102 if (__builtin_expect (*thisresplenp
<= 0, 0)) {
1103 if (errno
== EINTR
|| errno
== EAGAIN
) {
1107 Perror(statp
, stderr
, "recvfrom", errno
);
1111 if (__builtin_expect (*thisresplenp
< HFIXEDSZ
, 0)) {
1113 * Undersized message.
1115 Dprint(statp
->options
& RES_DEBUG
,
1116 (stdout
, ";; undersized: %d\n",
1121 if ((recvresp1
|| hp
->id
!= anhp
->id
)
1122 && (recvresp2
|| hp2
->id
!= anhp
->id
)) {
1124 * response from old query, ignore it.
1125 * XXX - potential security hazard could
1128 DprintQ((statp
->options
& RES_DEBUG
) ||
1129 (statp
->pfcode
& RES_PRF_REPLY
),
1130 (stdout
, ";; old answer:\n"),
1132 (*thisresplen
> *thisanssiz
)
1133 ? *thisanssiz
: *thisresplen
);
1136 if (!(statp
->options
& RES_INSECURE1
) &&
1137 !res_ourserver_p(statp
, &from
)) {
1139 * response from wrong server? ignore it.
1140 * XXX - potential security hazard could
1143 DprintQ((statp
->options
& RES_DEBUG
) ||
1144 (statp
->pfcode
& RES_PRF_REPLY
),
1145 (stdout
, ";; not our server:\n"),
1147 (*thisresplen
> *thisanssiz
)
1148 ? *thisanssiz
: *thisresplen
);
1151 #ifdef RES_USE_EDNS0
1152 if (anhp
->rcode
== FORMERR
1153 && (statp
->options
& RES_USE_EDNS0
) != 0U) {
1155 * Do not retry if the server does not understand
1156 * EDNS0. The case has to be captured here, as
1157 * FORMERR packet do not carry query section, hence
1158 * res_queriesmatch() returns 0.
1160 DprintQ(statp
->options
& RES_DEBUG
,
1162 "server rejected query with EDNS0:\n"),
1164 (*thisresplen
> *thisanssiz
)
1165 ? *thisanssiz
: *thisresplen
);
1166 /* record the error */
1167 statp
->_flags
|= RES_F_EDNS0ERR
;
1171 if (!(statp
->options
& RES_INSECURE2
)
1172 && (recvresp1
|| !res_queriesmatch(buf
, buf
+ buflen
,
1176 && (recvresp2
|| !res_queriesmatch(buf2
, buf2
+ buflen2
,
1181 * response contains wrong query? ignore it.
1182 * XXX - potential security hazard could
1185 DprintQ((statp
->options
& RES_DEBUG
) ||
1186 (statp
->pfcode
& RES_PRF_REPLY
),
1187 (stdout
, ";; wrong query name:\n"),
1189 (*thisresplen
> *thisanssiz
)
1190 ? *thisanssiz
: *thisresplen
);
1193 if (anhp
->rcode
== SERVFAIL
||
1194 anhp
->rcode
== NOTIMP
||
1195 anhp
->rcode
== REFUSED
) {
1196 DprintQ(statp
->options
& RES_DEBUG
,
1197 (stdout
, "server rejected query:\n"),
1199 (*thisresplen
> *thisanssiz
)
1200 ? *thisanssiz
: *thisresplen
);
1202 if (recvresp1
|| (buf2
!= NULL
&& recvresp2
))
1209 /* We are waiting for a possible second reply. */
1211 if (hp
->id
== anhp
->id
)
1220 __res_iclose(statp
, false);
1221 /* don't retry if called from dig */
1225 if (anhp
->rcode
== NOERROR
&& anhp
->ancount
== 0
1226 && anhp
->aa
== 0 && anhp
->ra
== 0 && anhp
->arcount
== 0) {
1227 DprintQ(statp
->options
& RES_DEBUG
,
1228 (stdout
, "referred query:\n"),
1230 (*thisresplen
> *thisanssiz
)
1231 ? *thisanssiz
: *thisresplen
);
1234 if (!(statp
->options
& RES_IGNTC
) && anhp
->tc
) {
1236 * To get the rest of answer,
1237 * use TCP with same server.
1239 Dprint(statp
->options
& RES_DEBUG
,
1240 (stdout
, ";; truncated answer\n"));
1242 __res_iclose(statp
, false);
1243 // XXX if we have received one reply we could
1244 // XXX use it and not repeat it over TCP...
1247 /* Mark which reply we received. */
1248 if (recvresp1
== 0 && hp
->id
== anhp
->id
)
1252 /* Repeat waiting if we have a second answer to arrive. */
1253 if ((recvresp1
& recvresp2
) == 0)
1256 * All is well, or the error is fatal. Signal that the
1257 * next nameserver ought not be tried.
1260 } else if (pfd
[0].revents
& (POLLERR
| POLLHUP
| POLLNVAL
)) {
1261 /* Something went wrong. We can stop trying. */
1265 /* poll should not have returned > 0 in this case. */
1272 Aerror(const res_state statp
, FILE *file
, const char *string
, int error
,
1273 const struct sockaddr
*address
)
1277 if ((statp
->options
& RES_DEBUG
) != 0) {
1278 char tmp
[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
1280 fprintf(file
, "res_send: %s ([%s].%u): %s\n",
1282 (address
->sa_family
== AF_INET
1283 ? inet_ntop(address
->sa_family
,
1284 &((const struct sockaddr_in
*) address
)->sin_addr
,
1286 : inet_ntop(address
->sa_family
,
1287 &((const struct sockaddr_in6
*) address
)->sin6_addr
,
1289 (address
->sa_family
== AF_INET
1290 ? ntohs(((struct sockaddr_in
*) address
)->sin_port
)
1291 : address
->sa_family
== AF_INET6
1292 ? ntohs(((struct sockaddr_in6
*) address
)->sin6_port
)
1300 Perror(const res_state statp
, FILE *file
, const char *string
, int error
) {
1303 if ((statp
->options
& RES_DEBUG
) != 0)
1304 fprintf(file
, "res_send: %s: %s\n",
1305 string
, strerror(error
));
1311 sock_eq(struct sockaddr_in6
*a1
, struct sockaddr_in6
*a2
) {
1312 if (a1
->sin6_family
== a2
->sin6_family
) {
1313 if (a1
->sin6_family
== AF_INET
)
1314 return ((((struct sockaddr_in
*)a1
)->sin_port
==
1315 ((struct sockaddr_in
*)a2
)->sin_port
) &&
1316 (((struct sockaddr_in
*)a1
)->sin_addr
.s_addr
==
1317 ((struct sockaddr_in
*)a2
)->sin_addr
.s_addr
));
1319 return ((a1
->sin6_port
== a2
->sin6_port
) &&
1320 !memcmp(&a1
->sin6_addr
, &a2
->sin6_addr
,
1321 sizeof (struct in6_addr
)));
1323 if (a1
->sin6_family
== AF_INET
) {
1324 struct sockaddr_in6
*sap
= a1
;
1327 } /* assumes that AF_INET and AF_INET6 are the only possibilities */
1328 return ((a1
->sin6_port
== ((struct sockaddr_in
*)a2
)->sin_port
) &&
1329 IN6_IS_ADDR_V4MAPPED(&a1
->sin6_addr
) &&
1330 (a1
->sin6_addr
.s6_addr32
[3] ==
1331 ((struct sockaddr_in
*)a2
)->sin_addr
.s_addr
));
1335 * Converts IPv4 family, address and port to
1336 * IPv6 family, IPv4-mapped IPv6 address and port.
1339 convaddr4to6(struct sockaddr_in6
*sa
)
1341 struct sockaddr_in
*sa4p
= (struct sockaddr_in
*) sa
;
1342 in_port_t port
= sa4p
->sin_port
;
1343 in_addr_t addr
= sa4p
->sin_addr
.s_addr
;
1345 sa
->sin6_family
= AF_INET6
;
1346 sa
->sin6_port
= port
;
1347 sa
->sin6_addr
.s6_addr32
[0] = 0;
1348 sa
->sin6_addr
.s6_addr32
[1] = 0;
1349 sa
->sin6_addr
.s6_addr32
[2] = htonl(0xFFFF);
1350 sa
->sin6_addr
.s6_addr32
[3] = addr
;