]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/resolv/res_send.c
Update to zstd 1.3.2
[FreeBSD/FreeBSD.git] / lib / libc / resolv / res_send.c
1 /*
2  * Portions Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
3  * Portions Copyright (C) 1996-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /*
19  * Copyright (c) 1985, 1989, 1993
20  *    The Regents of the University of California.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  * 3. Neither the name of the University nor the names of its contributors
31  *    may be used to endorse or promote products derived from this software
32  *    without specific prior written permission.
33  *
34  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  */
46
47 /*
48  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
49  *
50  * Permission to use, copy, modify, and distribute this software for any
51  * purpose with or without fee is hereby granted, provided that the above
52  * copyright notice and this permission notice appear in all copies, and that
53  * the name of Digital Equipment Corporation not be used in advertising or
54  * publicity pertaining to distribution of the document or software without
55  * specific, written prior permission.
56  *
57  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
58  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
59  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
60  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
61  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
62  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
63  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
64  * SOFTWARE.
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[] = "$Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp $";
70 #endif /* LIBC_SCCS and not lint */
71 #include <sys/cdefs.h>
72 __FBSDID("$FreeBSD$");
73
74 /*! \file
75  * \brief
76  * Send query to name server and wait for reply.
77  */
78
79 #include "port_before.h"
80 #if !defined(USE_KQUEUE) && !defined(USE_POLL)
81 #include "fd_setsize.h"
82 #endif
83
84 #include "namespace.h"
85 #include <sys/param.h>
86 #include <sys/time.h>
87 #include <sys/socket.h>
88 #include <sys/uio.h>
89
90 #include <netinet/in.h>
91 #include <arpa/nameser.h>
92 #include <arpa/inet.h>
93
94 #include <errno.h>
95 #include <netdb.h>
96 #include <resolv.h>
97 #include <signal.h>
98 #include <stdio.h>
99 #include <stdlib.h>
100 #include <string.h>
101 #include <unistd.h>
102
103 #include <isc/eventlib.h>
104
105 #include "port_after.h"
106
107 #ifdef USE_KQUEUE
108 #include <sys/event.h>
109 #else
110 #ifdef USE_POLL
111 #ifdef HAVE_STROPTS_H
112 #include <stropts.h>
113 #endif
114 #include <poll.h>
115 #endif /* USE_POLL */
116 #endif
117
118 #include "un-namespace.h"
119
120 /* Options.  Leave them on. */
121 #ifndef DEBUG
122 #define DEBUG
123 #endif
124 #include "res_debug.h"
125 #include "res_private.h"
126
127 #define EXT(res) ((res)->_u._ext)
128
129 #if !defined(USE_POLL) && !defined(USE_KQUEUE)
130 static const int highestFD = FD_SETSIZE - 1;
131 #endif
132
133 /* Forward. */
134
135 static int              get_salen(const struct sockaddr *);
136 static struct sockaddr * get_nsaddr(res_state, size_t);
137 static int              send_vc(res_state, const u_char *, int,
138                                 u_char *, int, int *, int);
139 static int              send_dg(res_state,
140 #ifdef USE_KQUEUE
141                                 int kq,
142 #endif
143                                 const u_char *, int,
144                                 u_char *, int, int *, int, int,
145                                 int *, int *);
146 static void             Aerror(const res_state, FILE *, const char *, int,
147                                const struct sockaddr *, int);
148 static void             Perror(const res_state, FILE *, const char *, int);
149 static int              sock_eq(struct sockaddr *, struct sockaddr *);
150 #if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE)
151 static int              pselect(int, void *, void *, void *,
152                                 struct timespec *,
153                                 const sigset_t *);
154 #endif
155 void res_pquery(const res_state, const u_char *, int, FILE *);
156
157 static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
158
159 /* Public. */
160
161 /*%
162  *      looks up "ina" in _res.ns_addr_list[]
163  *
164  * returns:
165  *\li   0  : not found
166  *\li   >0 : found
167  *
168  * author:
169  *\li   paul vixie, 29may94
170  */
171 int
172 res_ourserver_p(const res_state statp, const struct sockaddr *sa) {
173         const struct sockaddr_in *inp, *srv;
174         const struct sockaddr_in6 *in6p, *srv6;
175         int ns;
176
177         switch (sa->sa_family) {
178         case AF_INET:
179                 inp = (const struct sockaddr_in *)sa;
180                 for (ns = 0;  ns < statp->nscount;  ns++) {
181                         srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
182                         if (srv->sin_family == inp->sin_family &&
183                             srv->sin_port == inp->sin_port &&
184                             (srv->sin_addr.s_addr == INADDR_ANY ||
185                              srv->sin_addr.s_addr == inp->sin_addr.s_addr))
186                                 return (1);
187                 }
188                 break;
189         case AF_INET6:
190                 if (EXT(statp).ext == NULL)
191                         break;
192                 in6p = (const struct sockaddr_in6 *)sa;
193                 for (ns = 0;  ns < statp->nscount;  ns++) {
194                         srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
195                         if (srv6->sin6_family == in6p->sin6_family &&
196                             srv6->sin6_port == in6p->sin6_port &&
197 #ifdef HAVE_SIN6_SCOPE_ID
198                             (srv6->sin6_scope_id == 0 ||
199                              srv6->sin6_scope_id == in6p->sin6_scope_id) &&
200 #endif
201                             (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
202                              IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
203                                 return (1);
204                 }
205                 break;
206         default:
207                 break;
208         }
209         return (0);
210 }
211
212 /*%
213  *      look for (name,type,class) in the query section of packet (buf,eom)
214  *
215  * requires:
216  *\li   buf + HFIXEDSZ <= eom
217  *
218  * returns:
219  *\li   -1 : format error
220  *\li   0  : not found
221  *\li   >0 : found
222  *
223  * author:
224  *\li   paul vixie, 29may94
225  */
226 int
227 res_nameinquery(const char *name, int type, int class,
228                 const u_char *buf, const u_char *eom)
229 {
230         const u_char *cp = buf + HFIXEDSZ;
231         int qdcount = ntohs(((const HEADER*)buf)->qdcount);
232
233         while (qdcount-- > 0) {
234                 char tname[MAXDNAME+1];
235                 int n, ttype, tclass;
236
237                 n = dn_expand(buf, eom, cp, tname, sizeof tname);
238                 if (n < 0)
239                         return (-1);
240                 cp += n;
241                 if (cp + 2 * INT16SZ > eom)
242                         return (-1);
243                 ttype = ns_get16(cp); cp += INT16SZ;
244                 tclass = ns_get16(cp); cp += INT16SZ;
245                 if (ttype == type && tclass == class &&
246                     ns_samename(tname, name) == 1)
247                         return (1);
248         }
249         return (0);
250 }
251
252 /*%
253  *      is there a 1:1 mapping of (name,type,class)
254  *      in (buf1,eom1) and (buf2,eom2)?
255  *
256  * returns:
257  *\li   -1 : format error
258  *\li   0  : not a 1:1 mapping
259  *\li   >0 : is a 1:1 mapping
260  *
261  * author:
262  *\li   paul vixie, 29may94
263  */
264 int
265 res_queriesmatch(const u_char *buf1, const u_char *eom1,
266                  const u_char *buf2, const u_char *eom2)
267 {
268         const u_char *cp = buf1 + HFIXEDSZ;
269         int qdcount = ntohs(((const HEADER*)buf1)->qdcount);
270
271         if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
272                 return (-1);
273
274         /*
275          * Only header section present in replies to
276          * dynamic update packets.
277          */
278         if ((((const HEADER *)buf1)->opcode == ns_o_update) &&
279             (((const HEADER *)buf2)->opcode == ns_o_update))
280                 return (1);
281
282         if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))
283                 return (0);
284         while (qdcount-- > 0) {
285                 char tname[MAXDNAME+1];
286                 int n, ttype, tclass;
287
288                 n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
289                 if (n < 0)
290                         return (-1);
291                 cp += n;
292                 if (cp + 2 * INT16SZ > eom1)
293                         return (-1);
294                 ttype = ns_get16(cp);   cp += INT16SZ;
295                 tclass = ns_get16(cp); cp += INT16SZ;
296                 if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
297                         return (0);
298         }
299         return (1);
300 }
301
302 int
303 res_nsend(res_state statp,
304           const u_char *buf, int buflen, u_char *ans, int anssiz)
305 {
306         int gotsomewhere, terrno, tries, v_circuit, resplen, ns, n;
307 #ifdef USE_KQUEUE
308         int kq;
309 #endif
310         char abuf[NI_MAXHOST];
311
312         /* No name servers or res_init() failure */
313         if (statp->nscount == 0 || EXT(statp).ext == NULL) {
314                 errno = ESRCH;
315                 return (-1);
316         }
317         if (anssiz < HFIXEDSZ) {
318                 errno = EINVAL;
319                 return (-1);
320         }
321         DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
322                 (stdout, ";; res_send()\n"), buf, buflen);
323         v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
324         gotsomewhere = 0;
325         terrno = ETIMEDOUT;
326
327 #ifdef USE_KQUEUE
328         if ((kq = kqueue()) < 0) {
329                 Perror(statp, stderr, "kqueue", errno);
330                 return (-1);
331         }
332 #endif
333
334         /*
335          * If the ns_addr_list in the resolver context has changed, then
336          * invalidate our cached copy and the associated timing data.
337          */
338         if (EXT(statp).nscount != 0) {
339                 int needclose = 0;
340                 struct sockaddr_storage peer;
341                 ISC_SOCKLEN_T peerlen;
342
343                 if (EXT(statp).nscount != statp->nscount)
344                         needclose++;
345                 else
346                         for (ns = 0; ns < statp->nscount; ns++) {
347                                 if (statp->nsaddr_list[ns].sin_family &&
348                                     !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
349                                              (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
350                                         needclose++;
351                                         break;
352                                 }
353
354                                 if (EXT(statp).nssocks[ns] == -1)
355                                         continue;
356                                 peerlen = sizeof(peer);
357                                 if (_getpeername(EXT(statp).nssocks[ns],
358                                     (struct sockaddr *)&peer, &peerlen) < 0) {
359                                         needclose++;
360                                         break;
361                                 }
362                                 if (!sock_eq((struct sockaddr *)&peer,
363                                     get_nsaddr(statp, ns))) {
364                                         needclose++;
365                                         break;
366                                 }
367                         }
368                 if (needclose) {
369                         res_nclose(statp);
370                         EXT(statp).nscount = 0;
371                 }
372         }
373
374         /*
375          * Maybe initialize our private copy of the ns_addr_list.
376          */
377         if (EXT(statp).nscount == 0) {
378                 for (ns = 0; ns < statp->nscount; ns++) {
379                         EXT(statp).nstimes[ns] = RES_MAXTIME;
380                         EXT(statp).nssocks[ns] = -1;
381                         if (!statp->nsaddr_list[ns].sin_family)
382                                 continue;
383                         EXT(statp).ext->nsaddrs[ns].sin =
384                                  statp->nsaddr_list[ns];
385                 }
386                 EXT(statp).nscount = statp->nscount;
387         }
388
389         /*
390          * Some resolvers want to even out the load on their nameservers.
391          * Note that RES_BLAST overrides RES_ROTATE.
392          */
393         if ((statp->options & RES_ROTATE) != 0U &&
394             (statp->options & RES_BLAST) == 0U) {
395                 union res_sockaddr_union inu;
396                 struct sockaddr_in ina;
397                 int lastns = statp->nscount - 1;
398                 int fd;
399                 u_int16_t nstime;
400
401                 if (EXT(statp).ext != NULL)
402                         inu = EXT(statp).ext->nsaddrs[0];
403                 ina = statp->nsaddr_list[0];
404                 fd = EXT(statp).nssocks[0];
405                 nstime = EXT(statp).nstimes[0];
406                 for (ns = 0; ns < lastns; ns++) {
407                         if (EXT(statp).ext != NULL)
408                                 EXT(statp).ext->nsaddrs[ns] =
409                                         EXT(statp).ext->nsaddrs[ns + 1];
410                         statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
411                         EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
412                         EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
413                 }
414                 if (EXT(statp).ext != NULL)
415                         EXT(statp).ext->nsaddrs[lastns] = inu;
416                 statp->nsaddr_list[lastns] = ina;
417                 EXT(statp).nssocks[lastns] = fd;
418                 EXT(statp).nstimes[lastns] = nstime;
419         }
420
421         /*
422          * Send request, RETRY times, or until successful.
423          */
424         for (tries = 0; tries < statp->retry; tries++) {
425             for (ns = 0; ns < statp->nscount; ns++) {
426                 struct sockaddr *nsap;
427                 int nsaplen;
428                 nsap = get_nsaddr(statp, ns);
429                 nsaplen = get_salen(nsap);
430                 statp->_flags &= ~RES_F_LASTMASK;
431                 statp->_flags |= (ns << RES_F_LASTSHIFT);
432  same_ns:
433                 if (statp->qhook) {
434                         int done = 0, loops = 0;
435
436                         do {
437                                 res_sendhookact act;
438
439                                 act = (*statp->qhook)(&nsap, &buf, &buflen,
440                                                       ans, anssiz, &resplen);
441                                 switch (act) {
442                                 case res_goahead:
443                                         done = 1;
444                                         break;
445                                 case res_nextns:
446                                         res_nclose(statp);
447                                         goto next_ns;
448                                 case res_done:
449 #ifdef USE_KQUEUE
450                                         _close(kq);
451 #endif
452                                         return (resplen);
453                                 case res_modified:
454                                         /* give the hook another try */
455                                         if (++loops < 42) /*doug adams*/
456                                                 break;
457                                         /*FALLTHROUGH*/
458                                 case res_error:
459                                         /*FALLTHROUGH*/
460                                 default:
461                                         goto fail;
462                                 }
463                         } while (!done);
464                 }
465
466                 Dprint(((statp->options & RES_DEBUG) &&
467                         getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
468                                     NULL, 0, niflags) == 0),
469                        (stdout, ";; Querying server (# %d) address = %s\n",
470                         ns + 1, abuf));
471
472
473                 if (v_circuit) {
474                         /* Use VC; at most one attempt per server. */
475                         tries = statp->retry;
476                         n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
477                                     ns);
478                         if (n < 0)
479                                 goto fail;
480                         if (n == 0)
481                                 goto next_ns;
482                         resplen = n;
483                 } else {
484                         /* Use datagrams. */
485                         n = send_dg(statp,
486 #ifdef USE_KQUEUE
487                                     kq,
488 #endif
489                                     buf, buflen, ans, anssiz, &terrno,
490                                     ns, tries, &v_circuit, &gotsomewhere);
491                         if (n < 0)
492                                 goto fail;
493                         if (n == 0)
494                                 goto next_ns;
495                         if (v_circuit)
496                                 goto same_ns;
497                         resplen = n;
498                 }
499
500                 Dprint((statp->options & RES_DEBUG) ||
501                        ((statp->pfcode & RES_PRF_REPLY) &&
502                         (statp->pfcode & RES_PRF_HEAD1)),
503                        (stdout, ";; got answer:\n"));
504
505                 DprintQ((statp->options & RES_DEBUG) ||
506                         (statp->pfcode & RES_PRF_REPLY),
507                         (stdout, "%s", ""),
508                         ans, (resplen > anssiz) ? anssiz : resplen);
509
510                 /*
511                  * If we have temporarily opened a virtual circuit,
512                  * or if we haven't been asked to keep a socket open,
513                  * close the socket.
514                  */
515                 if ((v_circuit && (statp->options & RES_USEVC) == 0U) ||
516                     (statp->options & RES_STAYOPEN) == 0U) {
517                         res_nclose(statp);
518                 }
519                 if (statp->rhook) {
520                         int done = 0, loops = 0;
521
522                         do {
523                                 res_sendhookact act;
524
525                                 act = (*statp->rhook)(nsap, buf, buflen,
526                                                       ans, anssiz, &resplen);
527                                 switch (act) {
528                                 case res_goahead:
529                                 case res_done:
530                                         done = 1;
531                                         break;
532                                 case res_nextns:
533                                         res_nclose(statp);
534                                         goto next_ns;
535                                 case res_modified:
536                                         /* give the hook another try */
537                                         if (++loops < 42) /*doug adams*/
538                                                 break;
539                                         /*FALLTHROUGH*/
540                                 case res_error:
541                                         /*FALLTHROUGH*/
542                                 default:
543                                         goto fail;
544                                 }
545                         } while (!done);
546
547                 }
548 #ifdef USE_KQUEUE
549                 _close(kq);
550 #endif
551                 return (resplen);
552  next_ns: ;
553            } /*foreach ns*/
554         } /*foreach retry*/
555         res_nclose(statp);
556 #ifdef USE_KQUEUE
557         _close(kq);
558 #endif
559         if (!v_circuit) {
560                 if (!gotsomewhere)
561                         errno = ECONNREFUSED;   /*%< no nameservers found */
562                 else
563                         errno = ETIMEDOUT;      /*%< no answer obtained */
564         } else
565                 errno = terrno;
566         return (-1);
567  fail:
568         res_nclose(statp);
569 #ifdef USE_KQUEUE
570         _close(kq);
571 #endif
572         return (-1);
573 }
574
575 /* Private */
576
577 static int
578 get_salen(const struct sockaddr *sa)
579 {
580
581 #ifdef HAVE_SA_LEN
582         /* There are people do not set sa_len.  Be forgiving to them. */
583         if (sa->sa_len)
584                 return (sa->sa_len);
585 #endif
586
587         if (sa->sa_family == AF_INET)
588                 return (sizeof(struct sockaddr_in));
589         else if (sa->sa_family == AF_INET6)
590                 return (sizeof(struct sockaddr_in6));
591         else
592                 return (0);     /*%< unknown, die on connect */
593 }
594
595 /*%
596  * pick appropriate nsaddr_list for use.  see res_init() for initialization.
597  */
598 static struct sockaddr *
599 get_nsaddr(res_state statp, size_t n)
600 {
601
602         if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
603                 /*
604                  * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
605                  *   than struct sockaddr, and
606                  * - user code did not update statp->nsaddr_list[n].
607                  */
608                 return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n];
609         } else {
610                 /*
611                  * - user code updated statp->nsaddr_list[n], or
612                  * - statp->nsaddr_list[n] has the same content as
613                  *   EXT(statp).ext->nsaddrs[n].
614                  */
615                 return (struct sockaddr *)(void *)&statp->nsaddr_list[n];
616         }
617 }
618
619 static int
620 send_vc(res_state statp,
621         const u_char *buf, int buflen, u_char *ans, int anssiz,
622         int *terrno, int ns)
623 {
624         const HEADER *hp = (const HEADER *) buf;
625         HEADER *anhp = (HEADER *) ans;
626         struct sockaddr *nsap;
627         int nsaplen;
628         int truncating, connreset, resplen, n;
629         struct iovec iov[2];
630         u_short len;
631         u_char *cp;
632         void *tmp;
633 #ifdef SO_NOSIGPIPE
634         int on = 1;
635 #endif
636
637         nsap = get_nsaddr(statp, ns);
638         nsaplen = get_salen(nsap);
639
640         connreset = 0;
641  same_ns:
642         truncating = 0;
643
644         /* Are we still talking to whom we want to talk to? */
645         if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
646                 struct sockaddr_storage peer;
647                 ISC_SOCKLEN_T size = sizeof peer;
648
649                 if (_getpeername(statp->_vcsock,
650                                 (struct sockaddr *)&peer, &size) < 0 ||
651                     !sock_eq((struct sockaddr *)&peer, nsap)) {
652                         res_nclose(statp);
653                         statp->_flags &= ~RES_F_VC;
654                 }
655         }
656
657         if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
658                 if (statp->_vcsock >= 0)
659                         res_nclose(statp);
660
661                 statp->_vcsock = _socket(nsap->sa_family, SOCK_STREAM |
662                     SOCK_CLOEXEC, 0);
663 #if !defined(USE_POLL) && !defined(USE_KQUEUE)
664                 if (statp->_vcsock > highestFD) {
665                         res_nclose(statp);
666                         errno = ENOTSOCK;
667                 }
668 #endif
669                 if (statp->_vcsock < 0) {
670                         switch (errno) {
671                         case EPROTONOSUPPORT:
672 #ifdef EPFNOSUPPORT
673                         case EPFNOSUPPORT:
674 #endif
675                         case EAFNOSUPPORT:
676                                 Perror(statp, stderr, "socket(vc)", errno);
677                                 return (0);
678                         default:
679                                 *terrno = errno;
680                                 Perror(statp, stderr, "socket(vc)", errno);
681                                 return (-1);
682                         }
683                 }
684 #ifdef SO_NOSIGPIPE
685                 /*
686                  * Disable generation of SIGPIPE when writing to a closed
687                  * socket.  Write should return -1 and set errno to EPIPE
688                  * instead.
689                  *
690                  * Push on even if setsockopt(SO_NOSIGPIPE) fails.
691                  */
692                 (void)_setsockopt(statp->_vcsock, SOL_SOCKET, SO_NOSIGPIPE, &on,
693                                  sizeof(on));
694 #endif
695                 errno = 0;
696                 if (_connect(statp->_vcsock, nsap, nsaplen) < 0) {
697                         *terrno = errno;
698                         Aerror(statp, stderr, "connect/vc", errno, nsap,
699                             nsaplen);
700                         res_nclose(statp);
701                         return (0);
702                 }
703                 statp->_flags |= RES_F_VC;
704         }
705
706         /*
707          * Send length & message
708          */
709         ns_put16((u_short)buflen, (u_char*)&len);
710         iov[0] = evConsIovec(&len, INT16SZ);
711         DE_CONST(buf, tmp);
712         iov[1] = evConsIovec(tmp, buflen);
713         if (_writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
714                 *terrno = errno;
715                 Perror(statp, stderr, "write failed", errno);
716                 res_nclose(statp);
717                 return (0);
718         }
719         /*
720          * Receive length & response
721          */
722  read_len:
723         cp = ans;
724         len = INT16SZ;
725         while ((n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
726                 cp += n;
727                 if ((len -= n) == 0)
728                         break;
729         }
730         if (n <= 0) {
731                 *terrno = errno;
732                 Perror(statp, stderr, "read failed", errno);
733                 res_nclose(statp);
734                 /*
735                  * A long running process might get its TCP
736                  * connection reset if the remote server was
737                  * restarted.  Requery the server instead of
738                  * trying a new one.  When there is only one
739                  * server, this means that a query might work
740                  * instead of failing.  We only allow one reset
741                  * per query to prevent looping.
742                  */
743                 if (*terrno == ECONNRESET && !connreset) {
744                         connreset = 1;
745                         res_nclose(statp);
746                         goto same_ns;
747                 }
748                 res_nclose(statp);
749                 return (0);
750         }
751         resplen = ns_get16(ans);
752         if (resplen > anssiz) {
753                 Dprint(statp->options & RES_DEBUG,
754                        (stdout, ";; response truncated\n")
755                        );
756                 truncating = 1;
757                 len = anssiz;
758         } else
759                 len = resplen;
760         if (len < HFIXEDSZ) {
761                 /*
762                  * Undersized message.
763                  */
764                 Dprint(statp->options & RES_DEBUG,
765                        (stdout, ";; undersized: %d\n", len));
766                 *terrno = EMSGSIZE;
767                 res_nclose(statp);
768                 return (0);
769         }
770         cp = ans;
771         while (len != 0 &&
772             (n = _read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
773                 cp += n;
774                 len -= n;
775         }
776         if (n <= 0) {
777                 *terrno = errno;
778                 Perror(statp, stderr, "read(vc)", errno);
779                 res_nclose(statp);
780                 return (0);
781         }
782         if (truncating) {
783                 /*
784                  * Flush rest of answer so connection stays in synch.
785                  */
786                 anhp->tc = 1;
787                 len = resplen - anssiz;
788                 while (len != 0) {
789                         char junk[PACKETSZ];
790
791                         n = _read(statp->_vcsock, junk,
792                             (len > sizeof junk) ? sizeof junk : len);
793                         if (n > 0)
794                                 len -= n;
795                         else
796                                 break;
797                 }
798         }
799         /*
800          * If the calling applicating has bailed out of
801          * a previous call and failed to arrange to have
802          * the circuit closed or the server has got
803          * itself confused, then drop the packet and
804          * wait for the correct one.
805          */
806         if (hp->id != anhp->id) {
807                 DprintQ((statp->options & RES_DEBUG) ||
808                         (statp->pfcode & RES_PRF_REPLY),
809                         (stdout, ";; old answer (unexpected):\n"),
810                         ans, (resplen > anssiz) ? anssiz: resplen);
811                 goto read_len;
812         }
813
814         /*
815          * All is well, or the error is fatal.  Signal that the
816          * next nameserver ought not be tried.
817          */
818         return (resplen);
819 }
820
821 static int
822 send_dg(res_state statp,
823 #ifdef USE_KQUEUE
824         int kq,
825 #endif
826         const u_char *buf, int buflen, u_char *ans,
827         int anssiz, int *terrno, int ns, int tries, int *v_circuit,
828         int *gotsomewhere)
829 {
830         const HEADER *hp = (const HEADER *) buf;
831         HEADER *anhp = (HEADER *) ans;
832         const struct sockaddr *nsap;
833         int nsaplen;
834         struct timespec now, timeout, finish;
835         struct sockaddr_storage from;
836         ISC_SOCKLEN_T fromlen;
837         int resplen, seconds, n, s;
838 #ifdef USE_KQUEUE
839         struct kevent kv;
840 #else
841 #ifdef USE_POLL
842         int     polltimeout;
843         struct pollfd   pollfd;
844 #else
845         fd_set dsmask;
846 #endif
847 #endif
848
849         nsap = get_nsaddr(statp, ns);
850         nsaplen = get_salen(nsap);
851         if (EXT(statp).nssocks[ns] == -1) {
852                 EXT(statp).nssocks[ns] = _socket(nsap->sa_family,
853                     SOCK_DGRAM | SOCK_CLOEXEC, 0);
854 #if !defined(USE_POLL) && !defined(USE_KQUEUE)
855                 if (EXT(statp).nssocks[ns] > highestFD) {
856                         res_nclose(statp);
857                         errno = ENOTSOCK;
858                 }
859 #endif
860                 if (EXT(statp).nssocks[ns] < 0) {
861                         switch (errno) {
862                         case EPROTONOSUPPORT:
863 #ifdef EPFNOSUPPORT
864                         case EPFNOSUPPORT:
865 #endif
866                         case EAFNOSUPPORT:
867                                 Perror(statp, stderr, "socket(dg)", errno);
868                                 return (0);
869                         default:
870                                 *terrno = errno;
871                                 Perror(statp, stderr, "socket(dg)", errno);
872                                 return (-1);
873                         }
874                 }
875 #ifndef CANNOT_CONNECT_DGRAM
876                 /*
877                  * On a 4.3BSD+ machine (client and server,
878                  * actually), sending to a nameserver datagram
879                  * port with no nameserver will cause an
880                  * ICMP port unreachable message to be returned.
881                  * If our datagram socket is "connected" to the
882                  * server, we get an ECONNREFUSED error on the next
883                  * socket operation, and select returns if the
884                  * error message is received.  We can thus detect
885                  * the absence of a nameserver without timing out.
886                  *
887                  * When the option "insecure1" is specified, we'd
888                  * rather expect to see responses from an "unknown"
889                  * address.  In order to let the kernel accept such
890                  * responses, do not connect the socket here.
891                  * XXX: or do we need an explicit option to disable
892                  * connecting?
893                  */
894                 if (!(statp->options & RES_INSECURE1) &&
895                     _connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
896                         Aerror(statp, stderr, "connect(dg)", errno, nsap,
897                             nsaplen);
898                         res_nclose(statp);
899                         return (0);
900                 }
901 #endif /* !CANNOT_CONNECT_DGRAM */
902                 Dprint(statp->options & RES_DEBUG,
903                        (stdout, ";; new DG socket\n"))
904         }
905         s = EXT(statp).nssocks[ns];
906 #ifndef CANNOT_CONNECT_DGRAM
907         if (statp->options & RES_INSECURE1) {
908                 if (_sendto(s,
909                     (const char*)buf, buflen, 0, nsap, nsaplen) != buflen) {
910                         Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
911                         res_nclose(statp);
912                         return (0);
913                 }
914         } else if (send(s, (const char*)buf, buflen, 0) != buflen) {
915                 Perror(statp, stderr, "send", errno);
916                 res_nclose(statp);
917                 return (0);
918         }
919 #else /* !CANNOT_CONNECT_DGRAM */
920         if (_sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen)
921         {
922                 Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
923                 res_nclose(statp);
924                 return (0);
925         }
926 #endif /* !CANNOT_CONNECT_DGRAM */
927
928         /*
929          * Wait for reply.
930          */
931         seconds = (statp->retrans << tries);
932         if (ns > 0)
933                 seconds /= statp->nscount;
934         if (seconds <= 0)
935                 seconds = 1;
936         now = evNowTime();
937         timeout = evConsTime(seconds, 0);
938         finish = evAddTime(now, timeout);
939         goto nonow;
940  wait:
941         now = evNowTime();
942  nonow:
943 #ifndef USE_POLL
944         if (evCmpTime(finish, now) > 0)
945                 timeout = evSubTime(finish, now);
946         else
947                 timeout = evConsTime(0, 0);
948 #ifdef USE_KQUEUE
949         EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, 0);
950         n = _kevent(kq, &kv, 1, &kv, 1, &timeout);
951 #else
952         FD_ZERO(&dsmask);
953         FD_SET(s, &dsmask);
954         n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
955 #endif
956 #else
957         timeout = evSubTime(finish, now);
958         if (timeout.tv_sec < 0)
959                 timeout = evConsTime(0, 0);
960         polltimeout = 1000*timeout.tv_sec +
961                 timeout.tv_nsec/1000000;
962         pollfd.fd = s;
963         pollfd.events = POLLRDNORM;
964         n = _poll(&pollfd, 1, polltimeout);
965 #endif /* USE_POLL */
966
967         if (n == 0) {
968                 Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
969                 *gotsomewhere = 1;
970                 return (0);
971         }
972         if (n < 0) {
973                 if (errno == EINTR)
974                         goto wait;
975 #ifdef USE_KQUEUE
976                 Perror(statp, stderr, "kevent", errno);
977 #else
978 #ifndef USE_POLL
979                 Perror(statp, stderr, "select", errno);
980 #else
981                 Perror(statp, stderr, "poll", errno);
982 #endif /* USE_POLL */
983 #endif
984                 res_nclose(statp);
985                 return (0);
986         }
987 #ifdef USE_KQUEUE
988         if (kv.ident != s)
989                 goto wait;
990 #endif
991         errno = 0;
992         fromlen = sizeof(from);
993         resplen = _recvfrom(s, (char*)ans, anssiz,0,
994                            (struct sockaddr *)&from, &fromlen);
995         if (resplen <= 0) {
996                 Perror(statp, stderr, "recvfrom", errno);
997                 res_nclose(statp);
998                 return (0);
999         }
1000         *gotsomewhere = 1;
1001         if (resplen < HFIXEDSZ) {
1002                 /*
1003                  * Undersized message.
1004                  */
1005                 Dprint(statp->options & RES_DEBUG,
1006                        (stdout, ";; undersized: %d\n",
1007                         resplen));
1008                 *terrno = EMSGSIZE;
1009                 res_nclose(statp);
1010                 return (0);
1011         }
1012         if (hp->id != anhp->id) {
1013                 /*
1014                  * response from old query, ignore it.
1015                  * XXX - potential security hazard could
1016                  *       be detected here.
1017                  */
1018                 DprintQ((statp->options & RES_DEBUG) ||
1019                         (statp->pfcode & RES_PRF_REPLY),
1020                         (stdout, ";; old answer:\n"),
1021                         ans, (resplen > anssiz) ? anssiz : resplen);
1022                 goto wait;
1023         }
1024         if (!(statp->options & RES_INSECURE1) &&
1025             !res_ourserver_p(statp, (struct sockaddr *)&from)) {
1026                 /*
1027                  * response from wrong server? ignore it.
1028                  * XXX - potential security hazard could
1029                  *       be detected here.
1030                  */
1031                 DprintQ((statp->options & RES_DEBUG) ||
1032                         (statp->pfcode & RES_PRF_REPLY),
1033                         (stdout, ";; not our server:\n"),
1034                         ans, (resplen > anssiz) ? anssiz : resplen);
1035                 goto wait;
1036         }
1037 #ifdef RES_USE_EDNS0
1038         if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) {
1039                 /*
1040                  * Do not retry if the server do not understand EDNS0.
1041                  * The case has to be captured here, as FORMERR packet do not
1042                  * carry query section, hence res_queriesmatch() returns 0.
1043                  */
1044                 DprintQ(statp->options & RES_DEBUG,
1045                         (stdout, "server rejected query with EDNS0:\n"),
1046                         ans, (resplen > anssiz) ? anssiz : resplen);
1047                 /* record the error */
1048                 statp->_flags |= RES_F_EDNS0ERR;
1049                 res_nclose(statp);
1050                 return (0);
1051         }
1052 #endif
1053         if (!(statp->options & RES_INSECURE2) &&
1054             !res_queriesmatch(buf, buf + buflen,
1055                               ans, ans + anssiz)) {
1056                 /*
1057                  * response contains wrong query? ignore it.
1058                  * XXX - potential security hazard could
1059                  *       be detected here.
1060                  */
1061                 DprintQ((statp->options & RES_DEBUG) ||
1062                         (statp->pfcode & RES_PRF_REPLY),
1063                         (stdout, ";; wrong query name:\n"),
1064                         ans, (resplen > anssiz) ? anssiz : resplen);
1065                 goto wait;
1066         }
1067         if (anhp->rcode == SERVFAIL ||
1068             anhp->rcode == NOTIMP ||
1069             anhp->rcode == REFUSED) {
1070                 DprintQ(statp->options & RES_DEBUG,
1071                         (stdout, "server rejected query:\n"),
1072                         ans, (resplen > anssiz) ? anssiz : resplen);
1073                 res_nclose(statp);
1074                 /* don't retry if called from dig */
1075                 if (!statp->pfcode)
1076                         return (0);
1077         }
1078         if (!(statp->options & RES_IGNTC) && anhp->tc) {
1079                 /*
1080                  * To get the rest of answer,
1081                  * use TCP with same server.
1082                  */
1083                 Dprint(statp->options & RES_DEBUG,
1084                        (stdout, ";; truncated answer\n"));
1085                 *v_circuit = 1;
1086                 res_nclose(statp);
1087                 return (1);
1088         }
1089         /*
1090          * All is well, or the error is fatal.  Signal that the
1091          * next nameserver ought not be tried.
1092          */
1093         return (resplen);
1094 }
1095
1096 static void
1097 Aerror(const res_state statp, FILE *file, const char *string, int error,
1098        const struct sockaddr *address, int alen)
1099 {
1100         int save = errno;
1101         char hbuf[NI_MAXHOST];
1102         char sbuf[NI_MAXSERV];
1103
1104         if ((statp->options & RES_DEBUG) != 0U) {
1105                 if (getnameinfo(address, alen, hbuf, sizeof(hbuf),
1106                     sbuf, sizeof(sbuf), niflags)) {
1107                         strncpy(hbuf, "?", sizeof(hbuf) - 1);
1108                         hbuf[sizeof(hbuf) - 1] = '\0';
1109                         strncpy(sbuf, "?", sizeof(sbuf) - 1);
1110                         sbuf[sizeof(sbuf) - 1] = '\0';
1111                 }
1112                 fprintf(file, "res_send: %s ([%s].%s): %s\n",
1113                         string, hbuf, sbuf, strerror(error));
1114         }
1115         errno = save;
1116 }
1117
1118 static void
1119 Perror(const res_state statp, FILE *file, const char *string, int error) {
1120         int save = errno;
1121
1122         if ((statp->options & RES_DEBUG) != 0U)
1123                 fprintf(file, "res_send: %s: %s\n",
1124                         string, strerror(error));
1125         errno = save;
1126 }
1127
1128 static int
1129 sock_eq(struct sockaddr *a, struct sockaddr *b) {
1130         struct sockaddr_in *a4, *b4;
1131         struct sockaddr_in6 *a6, *b6;
1132
1133         if (a->sa_family != b->sa_family)
1134                 return 0;
1135         switch (a->sa_family) {
1136         case AF_INET:
1137                 a4 = (struct sockaddr_in *)a;
1138                 b4 = (struct sockaddr_in *)b;
1139                 return a4->sin_port == b4->sin_port &&
1140                     a4->sin_addr.s_addr == b4->sin_addr.s_addr;
1141         case AF_INET6:
1142                 a6 = (struct sockaddr_in6 *)a;
1143                 b6 = (struct sockaddr_in6 *)b;
1144                 return a6->sin6_port == b6->sin6_port &&
1145 #ifdef HAVE_SIN6_SCOPE_ID
1146                     a6->sin6_scope_id == b6->sin6_scope_id &&
1147 #endif
1148                     IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
1149         default:
1150                 return 0;
1151         }
1152 }
1153
1154 #if defined(NEED_PSELECT) && !defined(USE_POLL) && !defined(USE_KQUEUE)
1155 /* XXX needs to move to the porting library. */
1156 static int
1157 pselect(int nfds, void *rfds, void *wfds, void *efds,
1158         struct timespec *tsp, const sigset_t *sigmask)
1159 {
1160         struct timeval tv, *tvp;
1161         sigset_t sigs;
1162         int n;
1163
1164         if (tsp) {
1165                 tvp = &tv;
1166                 tv = evTimeVal(*tsp);
1167         } else
1168                 tvp = NULL;
1169         if (sigmask)
1170                 sigprocmask(SIG_SETMASK, sigmask, &sigs);
1171         n = select(nfds, rfds, wfds, efds, tvp);
1172         if (sigmask)
1173                 sigprocmask(SIG_SETMASK, &sigs, NULL);
1174         if (tsp)
1175                 *tsp = evTimeSpec(tv);
1176         return (n);
1177 }
1178 #endif