2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
5 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
10 * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
11 * Portions Copyright (C) 1996-2003 Internet Software Consortium.
13 * Permission to use, copy, modify, and/or distribute this software for any
14 * purpose with or without fee is hereby granted, provided that the above
15 * copyright notice and this permission notice appear in all copies.
17 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
18 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
20 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
22 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
27 * Copyright (c) 1985, 1989, 1993
28 * The Regents of the University of California. All rights reserved.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
62 * Permission to use, copy, modify, and distribute this software for any
63 * purpose with or without fee is hereby granted, provided that the above
64 * copyright notice and this permission notice appear in all copies, and that
65 * the name of Digital Equipment Corporation not be used in advertising or
66 * publicity pertaining to distribution of the document or software without
67 * specific, written prior permission.
69 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
70 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
71 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
72 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
73 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
74 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
75 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
79 #if defined(LIBC_SCCS) && !defined(lint)
80 static const char sccsid
[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
81 static const char rcsid
[] = "$Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp $";
82 #endif /* LIBC_SCCS and not lint */
86 * Send query to name server and wait for reply.
89 #include "port_before.h"
90 #include "fd_setsize.h"
92 #include <sys/types.h>
93 #include <sys/param.h>
95 #include <sys/socket.h>
98 #include <netinet/in.h>
99 #include <netinet/tcp.h>
100 #include <arpa/nameser.h>
101 #include <arpa/inet.h>
112 #include <isc/eventlib.h>
114 #include "port_after.h"
117 #ifdef HAVE_STROPTS_H
121 #endif /* USE_POLL */
123 /* Options. Leave them on. */
125 #include "res_debug.h"
126 #include "res_private.h"
128 #define EXT(res) ((res)->_u._ext)
131 static const int highestFD
= FD_SETSIZE
- 1;
133 static int highestFD
= 0;
138 static int get_salen
__P((const struct sockaddr
*));
139 static struct sockaddr
* get_nsaddr
__P((res_state
, size_t));
140 static int send_vc(res_state
, const u_char
*, int,
141 u_char
*, int, int *, int);
142 static int send_dg(res_state
, const u_char
*, int,
143 u_char
*, int, int *, int, int,
145 static void Aerror(const res_state
, FILE *, const char *, int,
146 const struct sockaddr
*, int);
147 static void Perror(const res_state
, FILE *, const char *, int);
148 static int sock_eq(struct sockaddr
*, struct sockaddr
*);
149 #if defined(NEED_PSELECT) && !defined(USE_POLL)
150 static int pselect(int, void *, void *, void *,
154 void res_pquery(const res_state
, const u_char
*, int, FILE *);
156 #ifndef ORIGINAL_ISC_CODE
157 #pragma weak __res_nameinquery = res_nameinquery
158 #pragma weak __res_queriesmatch = res_queriesmatch
159 #pragma weak res_nisourserver = res_ourserver_p
160 #endif /* ORIGINAL_ISC_CODE */
162 static const int niflags
= NI_NUMERICHOST
| NI_NUMERICSERV
;
167 * looks up "ina" in _res.ns_addr_list[]
174 *\li paul vixie, 29may94
177 res_ourserver_p(const res_state statp
, const struct sockaddr
*sa
) {
178 const struct sockaddr_in
*inp
, *srv
;
179 const struct sockaddr_in6
*in6p
, *srv6
;
182 switch (sa
->sa_family
) {
184 inp
= (const struct sockaddr_in
*)sa
;
185 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
186 srv
= (struct sockaddr_in
*)get_nsaddr(statp
, ns
);
187 if (srv
->sin_family
== inp
->sin_family
&&
188 srv
->sin_port
== inp
->sin_port
&&
189 (srv
->sin_addr
.s_addr
== INADDR_ANY
||
190 srv
->sin_addr
.s_addr
== inp
->sin_addr
.s_addr
))
195 if (EXT(statp
).ext
== NULL
)
197 in6p
= (const struct sockaddr_in6
*)sa
;
198 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
199 srv6
= (struct sockaddr_in6
*)get_nsaddr(statp
, ns
);
200 if (srv6
->sin6_family
== in6p
->sin6_family
&&
201 srv6
->sin6_port
== in6p
->sin6_port
&&
202 #ifdef HAVE_SIN6_SCOPE_ID
203 (srv6
->sin6_scope_id
== 0 ||
204 srv6
->sin6_scope_id
== in6p
->sin6_scope_id
) &&
206 (IN6_IS_ADDR_UNSPECIFIED(&srv6
->sin6_addr
) ||
207 IN6_ARE_ADDR_EQUAL(&srv6
->sin6_addr
, &in6p
->sin6_addr
)))
218 * look for (name,type,class) in the query section of packet (buf,eom)
221 *\li buf + HFIXEDSZ <= eom
224 *\li -1 : format error
229 *\li paul vixie, 29may94
232 res_nameinquery(const char *name
, int type
, int class,
233 const u_char
*buf
, const u_char
*eom
)
235 const u_char
*cp
= buf
+ HFIXEDSZ
;
236 int qdcount
= ntohs(((const HEADER
*)buf
)->qdcount
);
238 while (qdcount
-- > 0) {
239 char tname
[MAXDNAME
+1];
240 int n
, ttype
, tclass
;
242 n
= dn_expand(buf
, eom
, cp
, tname
, sizeof tname
);
246 if (cp
+ 2 * INT16SZ
> eom
)
248 ttype
= ns_get16(cp
); cp
+= INT16SZ
;
249 tclass
= ns_get16(cp
); cp
+= INT16SZ
;
250 if (ttype
== type
&& tclass
== class &&
251 ns_samename(tname
, name
) == 1)
258 * is there a 1:1 mapping of (name,type,class)
259 * in (buf1,eom1) and (buf2,eom2)?
262 *\li -1 : format error
263 *\li 0 : not a 1:1 mapping
264 *\li >0 : is a 1:1 mapping
267 *\li paul vixie, 29may94
270 res_queriesmatch(const u_char
*buf1
, const u_char
*eom1
,
271 const u_char
*buf2
, const u_char
*eom2
)
273 const u_char
*cp
= buf1
+ HFIXEDSZ
;
274 int qdcount
= ntohs(((const HEADER
*)buf1
)->qdcount
);
276 if (buf1
+ HFIXEDSZ
> eom1
|| buf2
+ HFIXEDSZ
> eom2
)
280 * Only header section present in replies to
281 * dynamic update packets.
283 if ((((const HEADER
*)buf1
)->opcode
== ns_o_update
) &&
284 (((const HEADER
*)buf2
)->opcode
== ns_o_update
))
287 if (qdcount
!= ntohs(((const HEADER
*)buf2
)->qdcount
))
289 while (qdcount
-- > 0) {
290 char tname
[MAXDNAME
+1];
291 int n
, ttype
, tclass
;
293 n
= dn_expand(buf1
, eom1
, cp
, tname
, sizeof tname
);
297 if (cp
+ 2 * INT16SZ
> eom1
)
299 ttype
= ns_get16(cp
); cp
+= INT16SZ
;
300 tclass
= ns_get16(cp
); cp
+= INT16SZ
;
301 if (!res_nameinquery(tname
, ttype
, tclass
, buf2
, eom2
))
308 res_nsend(res_state statp
,
309 const u_char
*buf
, int buflen
, u_char
*ans
, int anssiz
)
311 int gotsomewhere
, terrno
, tries
, v_circuit
, resplen
, ns
, n
;
312 char abuf
[NI_MAXHOST
];
315 highestFD
= sysconf(_SC_OPEN_MAX
) - 1;
318 /* No name servers or res_init() failure */
319 if (statp
->nscount
== 0 || EXT(statp
).ext
== NULL
) {
323 if (anssiz
< HFIXEDSZ
) {
327 DprintQ((statp
->options
& RES_DEBUG
) || (statp
->pfcode
& RES_PRF_QUERY
),
328 (stdout
, ";; res_send()\n"), buf
, buflen
);
329 v_circuit
= (statp
->options
& RES_USEVC
) || buflen
> PACKETSZ
;
334 * If the ns_addr_list in the resolver context has changed, then
335 * invalidate our cached copy and the associated timing data.
337 if (EXT(statp
).nscount
!= 0) {
339 struct sockaddr_storage peer
;
340 ISC_SOCKLEN_T peerlen
;
342 if (EXT(statp
).nscount
!= statp
->nscount
)
345 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
346 if (statp
->nsaddr_list
[ns
].sin_family
&&
347 !sock_eq((struct sockaddr
*)&statp
->nsaddr_list
[ns
],
348 (struct sockaddr
*)&EXT(statp
).ext
->nsaddrs
[ns
])) {
353 if (EXT(statp
).nssocks
[ns
] == -1)
355 peerlen
= sizeof(peer
);
356 if (getpeername(EXT(statp
).nssocks
[ns
],
357 (struct sockaddr
*)&peer
, &peerlen
) < 0) {
361 if (!sock_eq((struct sockaddr
*)&peer
,
362 get_nsaddr(statp
, ns
))) {
369 EXT(statp
).nscount
= 0;
374 * Maybe initialize our private copy of the ns_addr_list.
376 if (EXT(statp
).nscount
== 0) {
377 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
378 EXT(statp
).nstimes
[ns
] = RES_MAXTIME
;
379 EXT(statp
).nssocks
[ns
] = -1;
380 if (!statp
->nsaddr_list
[ns
].sin_family
)
382 EXT(statp
).ext
->nsaddrs
[ns
].sin
=
383 statp
->nsaddr_list
[ns
];
385 EXT(statp
).nscount
= statp
->nscount
;
389 * Some resolvers want to even out the load on their nameservers.
390 * Note that RES_BLAST overrides RES_ROTATE.
392 if ((statp
->options
& RES_ROTATE
) != 0U &&
393 (statp
->options
& RES_BLAST
) == 0U) {
394 union res_sockaddr_union inu
;
395 struct sockaddr_in ina
;
396 int lastns
= statp
->nscount
- 1;
400 if (EXT(statp
).ext
!= NULL
)
401 inu
= EXT(statp
).ext
->nsaddrs
[0];
402 ina
= statp
->nsaddr_list
[0];
403 fd
= EXT(statp
).nssocks
[0];
404 nstime
= EXT(statp
).nstimes
[0];
405 for (ns
= 0; ns
< lastns
; ns
++) {
406 if (EXT(statp
).ext
!= NULL
)
407 EXT(statp
).ext
->nsaddrs
[ns
] =
408 EXT(statp
).ext
->nsaddrs
[ns
+ 1];
409 statp
->nsaddr_list
[ns
] = statp
->nsaddr_list
[ns
+ 1];
410 EXT(statp
).nssocks
[ns
] = EXT(statp
).nssocks
[ns
+ 1];
411 EXT(statp
).nstimes
[ns
] = EXT(statp
).nstimes
[ns
+ 1];
413 if (EXT(statp
).ext
!= NULL
)
414 EXT(statp
).ext
->nsaddrs
[lastns
] = inu
;
415 statp
->nsaddr_list
[lastns
] = ina
;
416 EXT(statp
).nssocks
[lastns
] = fd
;
417 EXT(statp
).nstimes
[lastns
] = nstime
;
421 * Send request, RETRY times, or until successful.
423 for (tries
= 0; tries
< statp
->retry
; tries
++) {
424 for (ns
= 0; ns
< statp
->nscount
; ns
++) {
425 struct sockaddr
*nsap
;
427 nsap
= get_nsaddr(statp
, ns
);
428 nsaplen
= get_salen(nsap
);
429 statp
->_flags
&= ~RES_F_LASTMASK
;
430 statp
->_flags
|= (ns
<< RES_F_LASTSHIFT
);
433 int done
= 0, loops
= 0;
438 act
= (*statp
->qhook
)(&nsap
, &buf
, &buflen
,
439 ans
, anssiz
, &resplen
);
450 /* give the hook another try */
451 if (++loops
< 42) /*doug adams*/
462 Dprint(((statp
->options
& RES_DEBUG
) &&
463 getnameinfo(nsap
, nsaplen
, abuf
, sizeof(abuf
),
464 NULL
, 0, niflags
) == 0),
465 (stdout
, ";; Querying server (# %d) address = %s\n",
470 /* Use VC; at most one attempt per server. */
471 tries
= statp
->retry
;
472 n
= send_vc(statp
, buf
, buflen
, ans
, anssiz
, &terrno
,
481 n
= send_dg(statp
, buf
, buflen
, ans
, anssiz
, &terrno
,
482 ns
, tries
, &v_circuit
, &gotsomewhere
);
492 Dprint((statp
->options
& RES_DEBUG
) ||
493 ((statp
->pfcode
& RES_PRF_REPLY
) &&
494 (statp
->pfcode
& RES_PRF_HEAD1
)),
495 (stdout
, ";; got answer:\n"));
497 DprintQ((statp
->options
& RES_DEBUG
) ||
498 (statp
->pfcode
& RES_PRF_REPLY
),
500 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
503 * If we have temporarily opened a virtual circuit,
504 * or if we haven't been asked to keep a socket open,
507 if ((v_circuit
&& (statp
->options
& RES_USEVC
) == 0U) ||
508 (statp
->options
& RES_STAYOPEN
) == 0U) {
512 int done
= 0, loops
= 0;
517 act
= (*statp
->rhook
)(nsap
, buf
, buflen
,
518 ans
, anssiz
, &resplen
);
528 /* give the hook another try */
529 if (++loops
< 42) /*doug adams*/
547 errno
= ECONNREFUSED
; /*%< no nameservers found */
549 errno
= ETIMEDOUT
; /*%< no answer obtained */
562 const struct sockaddr
*sa
;
566 /* There are people do not set sa_len. Be forgiving to them. */
571 if (sa
->sa_family
== AF_INET
)
572 return (sizeof(struct sockaddr_in
));
573 else if (sa
->sa_family
== AF_INET6
)
574 return (sizeof(struct sockaddr_in6
));
576 return (0); /*%< unknown, die on connect */
580 * pick appropriate nsaddr_list for use. see res_init() for initialization.
582 static struct sockaddr
*
588 if (!statp
->nsaddr_list
[n
].sin_family
&& EXT(statp
).ext
) {
590 * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
591 * than struct sockaddr, and
592 * - user code did not update statp->nsaddr_list[n].
594 return (struct sockaddr
*)(void *)&EXT(statp
).ext
->nsaddrs
[n
];
597 * - user code updated statp->nsaddr_list[n], or
598 * - statp->nsaddr_list[n] has the same content as
599 * EXT(statp).ext->nsaddrs[n].
601 return (struct sockaddr
*)(void *)&statp
->nsaddr_list
[n
];
606 send_vc(res_state statp
,
607 const u_char
*buf
, int buflen
, u_char
*ans
, int anssiz
,
610 const HEADER
*hp
= (const HEADER
*) buf
;
611 HEADER
*anhp
= (HEADER
*) ans
;
612 struct sockaddr
*nsap
;
614 int truncating
, connreset
, resplen
, n
;
623 nsap
= get_nsaddr(statp
, ns
);
624 nsaplen
= get_salen(nsap
);
630 /* Are we still talking to whom we want to talk to? */
631 if (statp
->_vcsock
>= 0 && (statp
->_flags
& RES_F_VC
) != 0) {
632 struct sockaddr_storage peer
;
633 ISC_SOCKLEN_T size
= sizeof peer
;
635 if (getpeername(statp
->_vcsock
,
636 (struct sockaddr
*)&peer
, &size
) < 0 ||
637 !sock_eq((struct sockaddr
*)&peer
, nsap
)) {
639 statp
->_flags
&= ~RES_F_VC
;
643 if (statp
->_vcsock
< 0 || (statp
->_flags
& RES_F_VC
) == 0) {
644 if (statp
->_vcsock
>= 0)
647 statp
->_vcsock
= socket(nsap
->sa_family
, SOCK_STREAM
, 0);
648 if (statp
->_vcsock
> highestFD
) {
652 if (statp
->_vcsock
< 0) {
654 case EPROTONOSUPPORT
:
659 Perror(statp
, stderr
, "socket(vc)", errno
);
663 Perror(statp
, stderr
, "socket(vc)", errno
);
669 * Disable generation of SIGPIPE when writing to a closed
670 * socket. Write should return -1 and set errno to EPIPE
673 * Push on even if setsockopt(SO_NOSIGPIPE) fails.
675 (void)setsockopt(statp
->_vcsock
, SOL_SOCKET
, SO_NOSIGPIPE
, &on
,
678 #ifdef TCP_CONN_ABORT_THRESHOLD
680 * The default connection timeout is over two minutes.
681 * We need something more reasonable here. The default
682 * retrans value is 5 sec., then 10, 20, 40, on retries.
683 * TCP connect does its own retries, so we want just one
684 * reasonable timeout value. Using 2X retrans, which
685 * gives us a 10 sec. connect timeout. If we're waiting
686 * that long to connect, we probably want to give up and
687 * try the next DNS server in our list.
689 * It might be reasonable to do this for all callers,
690 * but for now do it only when we see MS_INTEROP in the
691 * environment (set in smbd and idmapd)
693 if (getenv("MS_INTEROP") != NULL
) {
695 conn_tmo
= statp
->retrans
* 2000; /* mSec */
696 (void)setsockopt(statp
->_vcsock
, IPPROTO_TCP
,
697 TCP_CONN_ABORT_THRESHOLD
, &conn_tmo
,
702 if (connect(statp
->_vcsock
, nsap
, nsaplen
) < 0) {
704 Aerror(statp
, stderr
, "connect/vc", errno
, nsap
,
709 statp
->_flags
|= RES_F_VC
;
713 * Send length & message
715 ns_put16((u_short
)buflen
, (u_char
*)&len
);
716 iov
[0] = evConsIovec(&len
, INT16SZ
);
718 iov
[1] = evConsIovec(tmp
, buflen
);
719 if (writev(statp
->_vcsock
, iov
, 2) != (INT16SZ
+ buflen
)) {
721 Perror(statp
, stderr
, "write failed", errno
);
726 * Receive length & response
731 while ((n
= read(statp
->_vcsock
, (char *)cp
, (int)len
)) > 0) {
738 Perror(statp
, stderr
, "read failed", errno
);
741 * A long running process might get its TCP
742 * connection reset if the remote server was
743 * restarted. Requery the server instead of
744 * trying a new one. When there is only one
745 * server, this means that a query might work
746 * instead of failing. We only allow one reset
747 * per query to prevent looping.
749 if (*terrno
== ECONNRESET
&& !connreset
) {
757 resplen
= ns_get16(ans
);
758 if (resplen
> anssiz
) {
759 Dprint(statp
->options
& RES_DEBUG
,
760 (stdout
, ";; response truncated\n")
766 if (len
< HFIXEDSZ
) {
768 * Undersized message.
770 Dprint(statp
->options
& RES_DEBUG
,
771 (stdout
, ";; undersized: %d\n", len
));
777 while (len
!= 0 && (n
= read(statp
->_vcsock
, (char *)cp
, (int)len
)) > 0){
783 Perror(statp
, stderr
, "read(vc)", errno
);
789 * Flush rest of answer so connection stays in synch.
792 len
= resplen
- anssiz
;
796 n
= read(statp
->_vcsock
, junk
,
797 (len
> sizeof junk
) ? sizeof junk
: len
);
805 * If the calling applicating has bailed out of
806 * a previous call and failed to arrange to have
807 * the circuit closed or the server has got
808 * itself confused, then drop the packet and
809 * wait for the correct one.
811 if (hp
->id
!= anhp
->id
) {
812 DprintQ((statp
->options
& RES_DEBUG
) ||
813 (statp
->pfcode
& RES_PRF_REPLY
),
814 (stdout
, ";; old answer (unexpected):\n"),
815 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
820 * All is well, or the error is fatal. Signal that the
821 * next nameserver ought not be tried.
827 send_dg(res_state statp
, const u_char
*buf
, int buflen
, u_char
*ans
,
828 int anssiz
, int *terrno
, int ns
, int tries
, int *v_circuit
,
831 const HEADER
*hp
= (const HEADER
*) buf
;
832 HEADER
*anhp
= (HEADER
*) ans
;
833 const struct sockaddr
*nsap
;
835 struct timespec now
, timeout
, finish
;
836 struct sockaddr_storage from
;
837 ISC_SOCKLEN_T fromlen
;
838 int resplen
, seconds
, n
, s
;
841 struct pollfd pollfd
;
846 nsap
= get_nsaddr(statp
, ns
);
847 nsaplen
= get_salen(nsap
);
848 if (EXT(statp
).nssocks
[ns
] == -1) {
849 EXT(statp
).nssocks
[ns
] = socket(nsap
->sa_family
, SOCK_DGRAM
, 0);
850 if (EXT(statp
).nssocks
[ns
] > highestFD
) {
854 if (EXT(statp
).nssocks
[ns
] < 0) {
856 case EPROTONOSUPPORT
:
861 Perror(statp
, stderr
, "socket(dg)", errno
);
865 Perror(statp
, stderr
, "socket(dg)", errno
);
869 #ifndef CANNOT_CONNECT_DGRAM
871 * On a 4.3BSD+ machine (client and server,
872 * actually), sending to a nameserver datagram
873 * port with no nameserver will cause an
874 * ICMP port unreachable message to be returned.
875 * If our datagram socket is "connected" to the
876 * server, we get an ECONNREFUSED error on the next
877 * socket operation, and select returns if the
878 * error message is received. We can thus detect
879 * the absence of a nameserver without timing out.
881 if (connect(EXT(statp
).nssocks
[ns
], nsap
, nsaplen
) < 0) {
882 Aerror(statp
, stderr
, "connect(dg)", errno
, nsap
,
887 #endif /* !CANNOT_CONNECT_DGRAM */
888 Dprint(statp
->options
& RES_DEBUG
,
889 (stdout
, ";; new DG socket\n"))
891 s
= EXT(statp
).nssocks
[ns
];
892 #ifndef CANNOT_CONNECT_DGRAM
893 if (send(s
, (const char*)buf
, buflen
, 0) != buflen
) {
894 Perror(statp
, stderr
, "send", errno
);
898 #else /* !CANNOT_CONNECT_DGRAM */
899 if (sendto(s
, (const char*)buf
, buflen
, 0, nsap
, nsaplen
) != buflen
)
901 Aerror(statp
, stderr
, "sendto", errno
, nsap
, nsaplen
);
905 #endif /* !CANNOT_CONNECT_DGRAM */
910 seconds
= (statp
->retrans
<< tries
);
912 seconds
/= statp
->nscount
;
916 timeout
= evConsTime(seconds
, 0);
917 finish
= evAddTime(now
, timeout
);
925 if (evCmpTime(finish
, now
) > 0)
926 timeout
= evSubTime(finish
, now
);
928 timeout
= evConsTime(0, 0);
929 n
= pselect(s
+ 1, &dsmask
, NULL
, NULL
, &timeout
, NULL
);
931 timeout
= evSubTime(finish
, now
);
932 if (timeout
.tv_sec
< 0)
933 timeout
= evConsTime(0, 0);
934 polltimeout
= 1000*timeout
.tv_sec
+
935 timeout
.tv_nsec
/1000000;
937 pollfd
.events
= POLLRDNORM
;
938 n
= poll(&pollfd
, 1, polltimeout
);
939 #endif /* USE_POLL */
942 Dprint(statp
->options
& RES_DEBUG
, (stdout
, ";; timeout\n"));
950 Perror(statp
, stderr
, "select", errno
);
952 Perror(statp
, stderr
, "poll", errno
);
953 #endif /* USE_POLL */
958 fromlen
= sizeof(from
);
959 resplen
= recvfrom(s
, (char*)ans
, anssiz
,0,
960 (struct sockaddr
*)&from
, &fromlen
);
962 Perror(statp
, stderr
, "recvfrom", errno
);
967 if (resplen
< HFIXEDSZ
) {
969 * Undersized message.
971 Dprint(statp
->options
& RES_DEBUG
,
972 (stdout
, ";; undersized: %d\n",
978 if (hp
->id
!= anhp
->id
) {
980 * response from old query, ignore it.
981 * XXX - potential security hazard could
984 DprintQ((statp
->options
& RES_DEBUG
) ||
985 (statp
->pfcode
& RES_PRF_REPLY
),
986 (stdout
, ";; old answer:\n"),
987 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
990 if (!(statp
->options
& RES_INSECURE1
) &&
991 !res_ourserver_p(statp
, (struct sockaddr
*)&from
)) {
993 * response from wrong server? ignore it.
994 * XXX - potential security hazard could
997 DprintQ((statp
->options
& RES_DEBUG
) ||
998 (statp
->pfcode
& RES_PRF_REPLY
),
999 (stdout
, ";; not our server:\n"),
1000 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1003 #ifdef RES_USE_EDNS0
1004 if (anhp
->rcode
== FORMERR
&& (statp
->options
& RES_USE_EDNS0
) != 0U) {
1006 * Do not retry if the server do not understand EDNS0.
1007 * The case has to be captured here, as FORMERR packet do not
1008 * carry query section, hence res_queriesmatch() returns 0.
1010 DprintQ(statp
->options
& RES_DEBUG
,
1011 (stdout
, "server rejected query with EDNS0:\n"),
1012 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1013 /* record the error */
1014 statp
->_flags
|= RES_F_EDNS0ERR
;
1019 if (!(statp
->options
& RES_INSECURE2
) &&
1020 !res_queriesmatch(buf
, buf
+ buflen
,
1021 ans
, ans
+ anssiz
)) {
1023 * response contains wrong query? ignore it.
1024 * XXX - potential security hazard could
1027 DprintQ((statp
->options
& RES_DEBUG
) ||
1028 (statp
->pfcode
& RES_PRF_REPLY
),
1029 (stdout
, ";; wrong query name:\n"),
1030 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1033 if (anhp
->rcode
== SERVFAIL
||
1034 anhp
->rcode
== NOTIMP
||
1035 anhp
->rcode
== REFUSED
) {
1036 DprintQ(statp
->options
& RES_DEBUG
,
1037 (stdout
, "server rejected query:\n"),
1038 ans
, (resplen
> anssiz
) ? anssiz
: resplen
);
1040 /* don't retry if called from dig */
1044 if (!(statp
->options
& RES_IGNTC
) && anhp
->tc
) {
1046 * To get the rest of answer,
1047 * use TCP with same server.
1049 Dprint(statp
->options
& RES_DEBUG
,
1050 (stdout
, ";; truncated answer\n"));
1056 * All is well, or the error is fatal. Signal that the
1057 * next nameserver ought not be tried.
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
];
1072 if ((statp
->options
& RES_DEBUG
) != 0U) {
1073 if (getnameinfo(address
, alen
, hbuf
, sizeof(hbuf
),
1074 sbuf
, sizeof(sbuf
), niflags
)) {
1075 strncpy(hbuf
, "?", sizeof(hbuf
) - 1);
1076 hbuf
[sizeof(hbuf
) - 1] = '\0';
1077 strncpy(sbuf
, "?", sizeof(sbuf
) - 1);
1078 sbuf
[sizeof(sbuf
) - 1] = '\0';
1080 fprintf(file
, "res_send: %s ([%s].%s): %s\n",
1081 string
, hbuf
, sbuf
, strerror(error
));
1087 Perror(const res_state statp
, FILE *file
, const char *string
, int error
) {
1090 if ((statp
->options
& RES_DEBUG
) != 0U)
1091 fprintf(file
, "res_send: %s: %s\n",
1092 string
, strerror(error
));
1097 sock_eq(struct sockaddr
*a
, struct sockaddr
*b
) {
1098 struct sockaddr_in
*a4
, *b4
;
1099 struct sockaddr_in6
*a6
, *b6
;
1101 if (a
->sa_family
!= b
->sa_family
)
1103 switch (a
->sa_family
) {
1105 a4
= (struct sockaddr_in
*)a
;
1106 b4
= (struct sockaddr_in
*)b
;
1107 return a4
->sin_port
== b4
->sin_port
&&
1108 a4
->sin_addr
.s_addr
== b4
->sin_addr
.s_addr
;
1110 a6
= (struct sockaddr_in6
*)a
;
1111 b6
= (struct sockaddr_in6
*)b
;
1112 return a6
->sin6_port
== b6
->sin6_port
&&
1113 #ifdef HAVE_SIN6_SCOPE_ID
1114 a6
->sin6_scope_id
== b6
->sin6_scope_id
&&
1116 IN6_ARE_ADDR_EQUAL(&a6
->sin6_addr
, &b6
->sin6_addr
);
1122 #if defined(NEED_PSELECT) && !defined(USE_POLL)
1123 /* XXX needs to move to the porting library. */
1125 pselect(int nfds
, void *rfds
, void *wfds
, void *efds
,
1126 struct timespec
*tsp
, const sigset_t
*sigmask
)
1128 struct timeval tv
, *tvp
;
1134 tv
= evTimeVal(*tsp
);
1138 sigprocmask(SIG_SETMASK
, sigmask
, &sigs
);
1139 n
= select(nfds
, rfds
, wfds
, efds
, tvp
);
1141 sigprocmask(SIG_SETMASK
, &sigs
, NULL
);
1143 *tsp
= evTimeSpec(tv
);