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