1 /* $NetBSD: res_send.c,v 1.25 2012/03/21 00:34:54 christos Exp $ */
4 * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright (C) 1996-2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
21 * Copyright (c) 1985, 1989, 1993
22 * The Regents of the University of California. All rights reserved.
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
29 * 2. Redistributions in binary form must reproduce the above copyright
30 * notice, this list of conditions and the following disclaimer in the
31 * documentation and/or other materials provided with the distribution.
32 * 3. All advertising materials mentioning features or use of this software
33 * must display the following acknowledgement:
34 * This product includes software developed by the University of
35 * California, Berkeley and its contributors.
36 * 4. Neither the name of the University nor the names of its contributors
37 * may be used to endorse or promote products derived from this software
38 * without specific prior written permission.
40 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
56 * Permission to use, copy, modify, and distribute this software for any
57 * purpose with or without fee is hereby granted, provided that the above
58 * copyright notice and this permission notice appear in all copies, and that
59 * the name of Digital Equipment Corporation not be used in advertising or
60 * publicity pertaining to distribution of the document or software without
61 * specific, written prior permission.
63 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
64 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
65 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
66 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
67 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
68 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
69 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
74 * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
75 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
77 * Permission to use, copy, modify, and distribute this software for any
78 * purpose with or without fee is hereby granted, provided that the above
79 * copyright notice and this permission notice appear in all copies.
81 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
82 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
83 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
84 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
85 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
86 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
87 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
90 #include <sys/cdefs.h>
91 #if defined(LIBC_SCCS) && !defined(lint)
93 static const char sccsid
[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
94 static const char rcsid
[] = "Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp";
96 __RCSID("$NetBSD: res_send.c,v 1.25 2012/03/21 00:34:54 christos Exp $");
98 #endif /* LIBC_SCCS and not lint */
102 * Send query to name server and wait for reply.
105 #include "namespace.h"
106 #include "port_before.h"
107 #include "fd_setsize.h"
109 #include <sys/types.h>
110 #include <sys/param.h>
111 #include <sys/time.h>
112 #include <sys/socket.h>
115 #include <netinet/in.h>
116 #include <arpa/nameser.h>
117 #include <arpa/inet.h>
129 #include <isc/eventlib.h>
131 #include "port_after.h"
135 __weak_alias(res_ourserver_p
,__res_ourserver_p
)
136 __weak_alias(res_nameinquery
,__res_nameinquery
)
137 __weak_alias(res_queriesmatch
,__res_queriesmatch
)
138 __weak_alias(res_nsend
,__res_nsend
)
144 #ifdef HAVE_STROPTS_H
148 #endif /* USE_POLL */
150 /* Options. Leave them on. */
154 #include "res_debug.h"
155 #include "res_private.h"
157 #define EXT(res) ((res)->_u._ext)
160 static const int highestFD
= FD_SETSIZE
- 1;
165 static int get_salen(const struct sockaddr
*);
166 static struct sockaddr
* get_nsaddr(res_state
, size_t);
167 static int send_vc(res_state
, const u_char
*, int,
168 u_char
*, int, int *, int);
169 static int send_dg(res_state
, const u_char
*, int,
170 u_char
*, int, int *, int, int,
172 static void Aerror(const res_state
, FILE *, const char *, int,
173 const struct sockaddr
*, int);
174 static void Perror(const res_state
, FILE *, const char *, int);
175 static int sock_eq(struct sockaddr
*, struct sockaddr
*);
176 #if defined(NEED_PSELECT) && !defined(USE_POLL)
177 static int pselect(int, void *, void *, void *,
181 void res_pquery(const res_state
, const u_char
*, int, FILE *);
183 static const int niflags
= NI_NUMERICHOST
| NI_NUMERICSERV
;
188 * looks up "ina" in _res.ns_addr_list[]
195 *\li paul vixie, 29may94
198 res_ourserver_p(const res_state statp
, const struct sockaddr
*sa
) {
199 const struct sockaddr_in
*inp
, *srv
;
200 const struct sockaddr_in6
*in6p
, *srv6
;
203 switch (sa
->sa_family
) {
205 inp
= (const struct sockaddr_in
*)(const void *)sa
;
206 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
207 srv
= (struct sockaddr_in
*)(void *)get_nsaddr(statp
, (size_t)ns
);
208 if (srv
->sin_family
== inp
->sin_family
&&
209 srv
->sin_port
== inp
->sin_port
&&
210 (srv
->sin_addr
.s_addr
== INADDR_ANY
||
211 srv
->sin_addr
.s_addr
== inp
->sin_addr
.s_addr
))
216 if (EXT(statp
).ext
== NULL
)
218 in6p
= (const struct sockaddr_in6
*)(const void *)sa
;
219 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
220 srv6
= (struct sockaddr_in6
*)(void *)get_nsaddr(statp
, (size_t)ns
);
221 if (srv6
->sin6_family
== in6p
->sin6_family
&&
222 srv6
->sin6_port
== in6p
->sin6_port
&&
223 #ifdef HAVE_SIN6_SCOPE_ID
224 (srv6
->sin6_scope_id
== 0 ||
225 srv6
->sin6_scope_id
== in6p
->sin6_scope_id
) &&
227 (IN6_IS_ADDR_UNSPECIFIED(&srv6
->sin6_addr
) ||
228 IN6_ARE_ADDR_EQUAL(&srv6
->sin6_addr
, &in6p
->sin6_addr
)))
239 * look for (name,type,class) in the query section of packet (buf,eom)
242 *\li buf + HFIXEDSZ <= eom
245 *\li -1 : format error
250 *\li paul vixie, 29may94
253 res_nameinquery(const char *name
, int type
, int class,
254 const u_char
*buf
, const u_char
*eom
)
256 const u_char
*cp
= buf
+ HFIXEDSZ
;
257 int qdcount
= ntohs(((const HEADER
*)(const void *)buf
)->qdcount
);
259 while (qdcount
-- > 0) {
260 char tname
[MAXDNAME
+1];
261 int n
, ttype
, tclass
;
263 n
= dn_expand(buf
, eom
, cp
, tname
, (int)sizeof tname
);
267 if (cp
+ 2 * INT16SZ
> eom
)
269 ttype
= ns_get16(cp
); cp
+= INT16SZ
;
270 tclass
= ns_get16(cp
); cp
+= INT16SZ
;
271 if (ttype
== type
&& tclass
== class &&
272 ns_samename(tname
, name
) == 1)
279 * is there a 1:1 mapping of (name,type,class)
280 * in (buf1,eom1) and (buf2,eom2)?
283 *\li -1 : format error
284 *\li 0 : not a 1:1 mapping
285 *\li >0 : is a 1:1 mapping
288 *\li paul vixie, 29may94
291 res_queriesmatch(const u_char
*buf1
, const u_char
*eom1
,
292 const u_char
*buf2
, const u_char
*eom2
)
294 const u_char
*cp
= buf1
+ HFIXEDSZ
;
295 int qdcount
= ntohs(((const HEADER
*)(const void *)buf1
)->qdcount
);
297 if (buf1
+ HFIXEDSZ
> eom1
|| buf2
+ HFIXEDSZ
> eom2
)
301 * Only header section present in replies to
302 * dynamic update packets.
304 if ((((const HEADER
*)(const void *)buf1
)->opcode
== ns_o_update
) &&
305 (((const HEADER
*)(const void *)buf2
)->opcode
== ns_o_update
))
308 if (qdcount
!= ntohs(((const HEADER
*)(const void *)buf2
)->qdcount
))
310 while (qdcount
-- > 0) {
311 char tname
[MAXDNAME
+1];
312 int n
, ttype
, tclass
;
314 n
= dn_expand(buf1
, eom1
, cp
, tname
, (int)sizeof tname
);
318 if (cp
+ 2 * INT16SZ
> eom1
)
320 ttype
= ns_get16(cp
); cp
+= INT16SZ
;
321 tclass
= ns_get16(cp
); cp
+= INT16SZ
;
322 if (!res_nameinquery(tname
, ttype
, tclass
, buf2
, eom2
))
329 res_nsend(res_state statp
,
330 const u_char
*buf
, int buflen
, u_char
*ans
, int anssiz
)
332 int gotsomewhere
, terrno
, tries
, v_circuit
, resplen
, ns
, n
;
333 char abuf
[NI_MAXHOST
];
335 (void)res_check(statp
, NULL
);
337 /* No name servers or res_init() failure */
338 if (statp
->nscount
== 0 || EXT(statp
).ext
== NULL
) {
342 if (anssiz
< HFIXEDSZ
) {
346 DprintQ((statp
->options
& RES_DEBUG
) || (statp
->pfcode
& RES_PRF_QUERY
),
347 (stdout
, ";; res_send()\n"), buf
, buflen
);
348 v_circuit
= (statp
->options
& RES_USEVC
) || buflen
> PACKETSZ
;
353 * If the ns_addr_list in the resolver context has changed, then
354 * invalidate our cached copy and the associated timing data.
356 if (EXT(statp
).nscount
!= 0) {
358 struct sockaddr_storage peer
;
359 ISC_SOCKLEN_T peerlen
;
361 if (EXT(statp
).nscount
!= statp
->nscount
)
364 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
365 if (statp
->nsaddr_list
[ns
].sin_family
&&
366 !sock_eq((struct sockaddr
*)(void *)&statp
->nsaddr_list
[ns
],
367 (struct sockaddr
*)(void *)&EXT(statp
).ext
->nsaddrs
[ns
])) {
372 if (EXT(statp
).nssocks
[ns
] == -1)
374 peerlen
= sizeof(peer
);
375 if (getpeername(EXT(statp
).nssocks
[ns
],
376 (struct sockaddr
*)(void *)&peer
, &peerlen
) < 0) {
380 if (!sock_eq((struct sockaddr
*)(void *)&peer
,
381 get_nsaddr(statp
, (size_t)ns
))) {
388 EXT(statp
).nscount
= 0;
393 * Maybe initialize our private copy of the ns_addr_list.
395 if (EXT(statp
).nscount
== 0) {
396 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
397 EXT(statp
).nstimes
[ns
] = RES_MAXTIME
;
398 EXT(statp
).nssocks
[ns
] = -1;
399 if (!statp
->nsaddr_list
[ns
].sin_family
)
401 EXT(statp
).ext
->nsaddrs
[ns
].sin
=
402 statp
->nsaddr_list
[ns
];
404 EXT(statp
).nscount
= statp
->nscount
;
408 * Some resolvers want to even out the load on their nameservers.
409 * Note that RES_BLAST overrides RES_ROTATE.
411 if ((statp
->options
& RES_ROTATE
) != 0U &&
412 (statp
->options
& RES_BLAST
) == 0U) {
413 union res_sockaddr_union inu
;
414 struct sockaddr_in ina
;
415 int lastns
= statp
->nscount
- 1;
419 if (EXT(statp
).ext
!= NULL
)
420 inu
= EXT(statp
).ext
->nsaddrs
[0];
421 ina
= statp
->nsaddr_list
[0];
422 fd
= EXT(statp
).nssocks
[0];
423 nstime
= EXT(statp
).nstimes
[0];
424 for (ns
= 0; ns
< lastns
; ns
++) {
425 if (EXT(statp
).ext
!= NULL
)
426 EXT(statp
).ext
->nsaddrs
[ns
] =
427 EXT(statp
).ext
->nsaddrs
[ns
+ 1];
428 statp
->nsaddr_list
[ns
] = statp
->nsaddr_list
[ns
+ 1];
429 EXT(statp
).nssocks
[ns
] = EXT(statp
).nssocks
[ns
+ 1];
430 EXT(statp
).nstimes
[ns
] = EXT(statp
).nstimes
[ns
+ 1];
432 if (EXT(statp
).ext
!= NULL
)
433 EXT(statp
).ext
->nsaddrs
[lastns
] = inu
;
434 statp
->nsaddr_list
[lastns
] = ina
;
435 EXT(statp
).nssocks
[lastns
] = fd
;
436 EXT(statp
).nstimes
[lastns
] = nstime
;
440 * Send request, RETRY times, or until successful.
442 for (tries
= 0; tries
< statp
->retry
; tries
++) {
443 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
444 struct sockaddr
*nsap
;
446 nsap
= get_nsaddr(statp
, (size_t)ns
);
447 nsaplen
= get_salen(nsap
);
448 statp
->_flags
&= ~RES_F_LASTMASK
;
449 statp
->_flags
|= (ns
<< RES_F_LASTSHIFT
);
452 int done
= 0, loops
= 0;
457 act
= (*statp
->qhook
)(&nsap
, &buf
, &buflen
,
458 ans
, anssiz
, &resplen
);
469 /* give the hook another try */
470 if (++loops
< 42) /*doug adams*/
481 Dprint(((statp
->options
& RES_DEBUG
) &&
482 getnameinfo(nsap
, (socklen_t
)nsaplen
, abuf
,
483 (socklen_t
)sizeof(abuf
), NULL
, 0, niflags
) == 0),
484 (stdout
, ";; Querying server (# %d) address = %s\n",
489 /* Use VC; at most one attempt per server. */
490 tries
= statp
->retry
;
491 n
= send_vc(statp
, buf
, buflen
, ans
, anssiz
, &terrno
,
500 n
= send_dg(statp
, buf
, buflen
, ans
, anssiz
, &terrno
,
501 ns
, tries
, &v_circuit
, &gotsomewhere
);
511 Dprint((statp
->options
& RES_DEBUG
) ||
512 ((statp
->pfcode
& RES_PRF_REPLY
) &&
513 (statp
->pfcode
& RES_PRF_HEAD1
)),
514 (stdout
, ";; got answer:\n"));
516 DprintQ((statp
->options
& RES_DEBUG
) ||
517 (statp
->pfcode
& RES_PRF_REPLY
),
519 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
522 * If we have temporarily opened a virtual circuit,
523 * or if we haven't been asked to keep a socket open,
526 if ((v_circuit
&& (statp
->options
& RES_USEVC
) == 0U) ||
527 (statp
->options
& RES_STAYOPEN
) == 0U) {
531 int done
= 0, loops
= 0;
536 act
= (*statp
->rhook
)(nsap
, buf
, buflen
,
537 ans
, anssiz
, &resplen
);
547 /* give the hook another try */
548 if (++loops
< 42) /*doug adams*/
566 errno
= ECONNREFUSED
; /*%< no nameservers found */
568 errno
= ETIMEDOUT
; /*%< no answer obtained */
580 get_salen(const struct sockaddr
*sa
)
584 /* There are people do not set sa_len. Be forgiving to them. */
589 if (sa
->sa_family
== AF_INET
)
590 return (sizeof(struct sockaddr_in
));
591 else if (sa
->sa_family
== AF_INET6
)
592 return (sizeof(struct sockaddr_in6
));
594 return (0); /*%< unknown, die on connect */
598 * pick appropriate nsaddr_list for use. see res_init() for initialization.
600 static struct sockaddr
*
601 get_nsaddr(res_state statp
, size_t n
)
604 if (!statp
->nsaddr_list
[n
].sin_family
&& EXT(statp
).ext
) {
606 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
607 * than struct sockaddr, and
608 * - user code did not update statp->nsaddr_list[n].
610 return (struct sockaddr
*)(void *)&EXT(statp
).ext
->nsaddrs
[n
];
613 * - user code updated statp->nsaddr_list[n], or
614 * - statp->nsaddr_list[n] has the same content as
615 * EXT(statp).ext->nsaddrs[n].
617 return (struct sockaddr
*)(void *)&statp
->nsaddr_list
[n
];
622 send_vc(res_state statp
,
623 const u_char
*buf
, int buflen
, u_char
*ans
, int anssiz
,
626 const HEADER
*hp
= (const HEADER
*)(const void *)buf
;
627 HEADER
*anhp
= (HEADER
*)(void *)ans
;
628 struct sockaddr
*nsap
;
630 int truncating
, connreset
, resplen
;
640 nsap
= get_nsaddr(statp
, (size_t)ns
);
641 nsaplen
= get_salen(nsap
);
647 /* Are we still talking to whom we want to talk to? */
648 if (statp
->_vcsock
>= 0 && (statp
->_flags
& RES_F_VC
) != 0) {
649 struct sockaddr_storage peer
;
650 ISC_SOCKLEN_T size
= sizeof peer
;
652 if (getpeername(statp
->_vcsock
,
653 (struct sockaddr
*)(void *)&peer
, &size
) < 0 ||
654 !sock_eq((struct sockaddr
*)(void *)&peer
, nsap
)) {
656 statp
->_flags
&= ~RES_F_VC
;
660 if (statp
->_vcsock
< 0 || (statp
->_flags
& RES_F_VC
) == 0) {
661 if (statp
->_vcsock
>= 0)
664 statp
->_vcsock
= socket(nsap
->sa_family
, SOCK_STREAM
, 0);
666 if (statp
->_vcsock
> highestFD
) {
671 if (statp
->_vcsock
< 0) {
673 case EPROTONOSUPPORT
:
678 Perror(statp
, stderr
, "socket(vc)", errno
);
682 Perror(statp
, stderr
, "socket(vc)", errno
);
688 * Disable generation of SIGPIPE when writing to a closed
689 * socket. Write should return -1 and set errno to EPIPE
692 * Push on even if setsockopt(SO_NOSIGPIPE) fails.
694 (void)setsockopt(statp
->_vcsock
, SOL_SOCKET
, SO_NOSIGPIPE
, &on
,
695 (unsigned int)sizeof(on
));
698 if (connect(statp
->_vcsock
, nsap
, (socklen_t
)nsaplen
) < 0) {
700 Aerror(statp
, stderr
, "connect/vc", errno
, nsap
,
705 statp
->_flags
|= RES_F_VC
;
709 * Send length & message
711 ns_put16((u_short
)buflen
, (u_char
*)(void *)&len
);
712 iov
[0] = evConsIovec(&len
, INT16SZ
);
714 iov
[1] = evConsIovec(tmp
, (size_t)buflen
);
715 if (writev(statp
->_vcsock
, iov
, 2) != (INT16SZ
+ buflen
)) {
717 Perror(statp
, stderr
, "write failed", errno
);
722 * Receive length & response
727 while ((n
= read(statp
->_vcsock
, (char *)cp
, (size_t)len
)) > 0) {
729 if ((len
-= (u_short
)n
) == 0)
734 Perror(statp
, stderr
, "read failed", errno
);
737 * A long running process might get its TCP
738 * connection reset if the remote server was
739 * restarted. Requery the server instead of
740 * trying a new one. When there is only one
741 * server, this means that a query might work
742 * instead of failing. We only allow one reset
743 * per query to prevent looping.
745 if (*terrno
== ECONNRESET
&& !connreset
) {
753 resplen
= ns_get16(ans
);
754 if (resplen
> anssiz
) {
755 Dprint(statp
->options
& RES_DEBUG
,
756 (stdout
, ";; response truncated\n")
762 if (len
< HFIXEDSZ
) {
764 * Undersized message.
766 Dprint(statp
->options
& RES_DEBUG
,
767 (stdout
, ";; undersized: %d\n", len
));
773 while (len
!= 0 && (n
= read(statp
->_vcsock
, (char *)cp
, (size_t)len
)) > 0){
779 Perror(statp
, stderr
, "read(vc)", errno
);
785 * Flush rest of answer so connection stays in synch.
788 len
= resplen
- anssiz
;
792 n
= read(statp
->_vcsock
, junk
,
793 (len
> sizeof junk
) ? sizeof junk
: len
);
801 * If the calling applicating has bailed out of
802 * a previous call and failed to arrange to have
803 * the circuit closed or the server has got
804 * itself confused, then drop the packet and
805 * wait for the correct one.
807 if (hp
->id
!= anhp
->id
) {
808 DprintQ((statp
->options
& RES_DEBUG
) ||
809 (statp
->pfcode
& RES_PRF_REPLY
),
810 (stdout
, ";; old answer (unexpected):\n"),
811 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
816 * All is well, or the error is fatal. Signal that the
817 * next nameserver ought not be tried.
823 send_dg(res_state statp
, const u_char
*buf
, int buflen
, u_char
*ans
,
824 int anssiz
, int *terrno
, int ns
, int tries
, int *v_circuit
,
827 const HEADER
*hp
= (const HEADER
*)(const void *)buf
;
828 HEADER
*anhp
= (HEADER
*)(void *)ans
;
829 const struct sockaddr
*nsap
;
831 struct timespec now
, timeout
, finish
;
832 struct sockaddr_storage from
;
833 ISC_SOCKLEN_T fromlen
;
838 struct pollfd pollfd
;
843 nsap
= get_nsaddr(statp
, (size_t)ns
);
844 nsaplen
= get_salen(nsap
);
845 if (EXT(statp
).nssocks
[ns
] == -1) {
846 EXT(statp
).nssocks
[ns
] = socket(nsap
->sa_family
, SOCK_DGRAM
, 0);
848 if (EXT(statp
).nssocks
[ns
] > highestFD
) {
853 if (EXT(statp
).nssocks
[ns
] < 0) {
855 case EPROTONOSUPPORT
:
860 Perror(statp
, stderr
, "socket(dg)", errno
);
864 Perror(statp
, stderr
, "socket(dg)", errno
);
868 #ifndef CANNOT_CONNECT_DGRAM
870 * On a 4.3BSD+ machine (client and server,
871 * actually), sending to a nameserver datagram
872 * port with no nameserver will cause an
873 * ICMP port unreachable message to be returned.
874 * If our datagram socket is "connected" to the
875 * server, we get an ECONNREFUSED error on the next
876 * socket operation, and select returns if the
877 * error message is received. We can thus detect
878 * the absence of a nameserver without timing out.
880 if (connect(EXT(statp
).nssocks
[ns
], nsap
, (socklen_t
)nsaplen
) < 0) {
881 Aerror(statp
, stderr
, "connect(dg)", errno
, nsap
,
886 #endif /* !CANNOT_CONNECT_DGRAM */
887 Dprint(statp
->options
& RES_DEBUG
,
888 (stdout
, ";; new DG socket\n"))
890 s
= EXT(statp
).nssocks
[ns
];
891 #ifndef CANNOT_CONNECT_DGRAM
892 if (send(s
, (const char*)buf
, (size_t)buflen
, 0) != buflen
) {
893 Perror(statp
, stderr
, "send", errno
);
897 #else /* !CANNOT_CONNECT_DGRAM */
898 if (sendto(s
, (const char*)buf
, buflen
, 0, nsap
, nsaplen
) != buflen
)
900 Aerror(statp
, stderr
, "sendto", errno
, nsap
, nsaplen
);
904 #endif /* !CANNOT_CONNECT_DGRAM */
909 seconds
= (statp
->retrans
<< tries
);
911 seconds
/= statp
->nscount
;
915 timeout
= evConsTime((time_t)seconds
, 0L);
916 finish
= evAddTime(now
, timeout
);
924 if (evCmpTime(finish
, now
) > 0)
925 timeout
= evSubTime(finish
, now
);
927 timeout
= evConsTime(0L, 0L);
928 n
= pselect(s
+ 1, &dsmask
, NULL
, NULL
, &timeout
, NULL
);
930 timeout
= evSubTime(finish
, now
);
931 if (timeout
.tv_sec
< 0)
932 timeout
= evConsTime((time_t)0, 0L);
933 polltimeout
= 1000*(int)timeout
.tv_sec
+
934 (int)timeout
.tv_nsec
/1000000;
936 pollfd
.events
= POLLRDNORM
;
937 n
= poll(&pollfd
, 1, polltimeout
);
938 #endif /* USE_POLL */
941 Dprint(statp
->options
& RES_DEBUG
, (stdout
, ";; timeout\n"));
949 Perror(statp
, stderr
, "select", errno
);
951 Perror(statp
, stderr
, "poll", errno
);
952 #endif /* USE_POLL */
957 fromlen
= sizeof(from
);
958 resplen
= recvfrom(s
, (char*)ans
, (size_t)anssiz
,0,
959 (struct sockaddr
*)(void *)&from
, &fromlen
);
961 Perror(statp
, stderr
, "recvfrom", errno
);
966 if (resplen
< HFIXEDSZ
) {
968 * Undersized message.
970 Dprint(statp
->options
& RES_DEBUG
,
971 (stdout
, ";; undersized: %zd\n",
977 if (hp
->id
!= anhp
->id
) {
979 * response from old query, ignore it.
980 * XXX - potential security hazard could
983 DprintQ((statp
->options
& RES_DEBUG
) ||
984 (statp
->pfcode
& RES_PRF_REPLY
),
985 (stdout
, ";; old answer:\n"),
986 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
989 if (!(statp
->options
& RES_INSECURE1
) &&
990 !res_ourserver_p(statp
, (struct sockaddr
*)(void *)&from
)) {
992 * response from wrong server? ignore it.
993 * XXX - potential security hazard could
996 DprintQ((statp
->options
& RES_DEBUG
) ||
997 (statp
->pfcode
& RES_PRF_REPLY
),
998 (stdout
, ";; not our server:\n"),
999 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1002 #ifdef RES_USE_EDNS0
1003 if (anhp
->rcode
== FORMERR
&& (statp
->options
& RES_USE_EDNS0
) != 0U) {
1005 * Do not retry if the server do not understand EDNS0.
1006 * The case has to be captured here, as FORMERR packet do not
1007 * carry query section, hence res_queriesmatch() returns 0.
1009 DprintQ(statp
->options
& RES_DEBUG
,
1010 (stdout
, "server rejected query with EDNS0:\n"),
1011 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1012 /* record the error */
1013 statp
->_flags
|= RES_F_EDNS0ERR
;
1018 if (!(statp
->options
& RES_INSECURE2
) &&
1019 !res_queriesmatch(buf
, buf
+ buflen
,
1020 ans
, ans
+ anssiz
)) {
1022 * response contains wrong query? ignore it.
1023 * XXX - potential security hazard could
1026 DprintQ((statp
->options
& RES_DEBUG
) ||
1027 (statp
->pfcode
& RES_PRF_REPLY
),
1028 (stdout
, ";; wrong query name:\n"),
1029 ans
, (int)(resplen
> anssiz
) ? anssiz
: resplen
);
1032 if (anhp
->rcode
== SERVFAIL
||
1033 anhp
->rcode
== NOTIMP
||
1034 anhp
->rcode
== REFUSED
) {
1035 DprintQ(statp
->options
& RES_DEBUG
,
1036 (stdout
, "server rejected query:\n"),
1037 ans
, (int)(resplen
> anssiz
) ? anssiz
: resplen
);
1039 /* don't retry if called from dig */
1043 if (!(statp
->options
& RES_IGNTC
) && anhp
->tc
) {
1045 * To get the rest of answer,
1046 * use TCP with same server.
1048 Dprint(statp
->options
& RES_DEBUG
,
1049 (stdout
, ";; truncated answer\n"));
1055 * All is well, or the error is fatal. Signal that the
1056 * next nameserver ought not be tried.
1058 _DIAGASSERT(__type_fit(int, resplen
));
1059 return (int)resplen
;
1063 Aerror(const res_state statp
, FILE *file
, const char *string
, int error
,
1064 const struct sockaddr
*address
, int alen
)
1067 char hbuf
[NI_MAXHOST
];
1068 char sbuf
[NI_MAXSERV
];
1070 if ((statp
->options
& RES_DEBUG
) != 0U) {
1071 if (getnameinfo(address
, (socklen_t
)alen
, hbuf
,
1072 (socklen_t
)sizeof(hbuf
), sbuf
, (socklen_t
)sizeof(sbuf
),
1074 strncpy(hbuf
, "?", sizeof(hbuf
) - 1);
1075 hbuf
[sizeof(hbuf
) - 1] = '\0';
1076 strncpy(sbuf
, "?", sizeof(sbuf
) - 1);
1077 sbuf
[sizeof(sbuf
) - 1] = '\0';
1079 fprintf(file
, "res_send: %s ([%s].%s): %s\n",
1080 string
, hbuf
, sbuf
, strerror(error
));
1086 Perror(const res_state statp
, FILE *file
, const char *string
, int error
) {
1089 if ((statp
->options
& RES_DEBUG
) != 0U)
1090 fprintf(file
, "res_send: %s: %s\n",
1091 string
, strerror(error
));
1096 sock_eq(struct sockaddr
*a
, struct sockaddr
*b
) {
1097 struct sockaddr_in
*a4
, *b4
;
1098 struct sockaddr_in6
*a6
, *b6
;
1100 if (a
->sa_family
!= b
->sa_family
)
1102 switch (a
->sa_family
) {
1104 a4
= (struct sockaddr_in
*)(void *)a
;
1105 b4
= (struct sockaddr_in
*)(void *)b
;
1106 return a4
->sin_port
== b4
->sin_port
&&
1107 a4
->sin_addr
.s_addr
== b4
->sin_addr
.s_addr
;
1109 a6
= (struct sockaddr_in6
*)(void *)a
;
1110 b6
= (struct sockaddr_in6
*)(void *)b
;
1111 return a6
->sin6_port
== b6
->sin6_port
&&
1112 #ifdef HAVE_SIN6_SCOPE_ID
1113 a6
->sin6_scope_id
== b6
->sin6_scope_id
&&
1115 IN6_ARE_ADDR_EQUAL(&a6
->sin6_addr
, &b6
->sin6_addr
);
1121 #if defined(NEED_PSELECT) && !defined(USE_POLL)
1122 /* XXX needs to move to the porting library. */
1124 pselect(int nfds
, void *rfds
, void *wfds
, void *efds
,
1125 struct timespec
*tsp
, const sigset_t
*sigmask
)
1127 struct timeval tv
, *tvp
;
1133 tv
= evTimeVal(*tsp
);
1137 sigprocmask(SIG_SETMASK
, sigmask
, &sigs
);
1138 n
= select(nfds
, rfds
, wfds
, efds
, tvp
);
1140 sigprocmask(SIG_SETMASK
, &sigs
, NULL
);
1142 *tsp
= evTimeSpec(tv
);