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