1/* dnsmasq is Copyright (c) 2000 - 2005 Simon Kelley 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 dated June, 1991. 6 7 This program is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 GNU General Public License for more details. 11*/ 12 13#include "dnsmasq.h" 14 15static struct frec *frec_list = NULL; 16 17static struct frec *get_new_frec(struct daemon *daemon, time_t now); 18static struct frec *lookup_frec(unsigned short id); 19static struct frec *lookup_frec_by_sender(unsigned short id, 20 union mysockaddr *addr, 21 unsigned int crc); 22static unsigned short get_id(void); 23 24 25/* Send a UDP packet with it's source address set as "source" 26 unless nowild is true, when we just send it with the kernel default */ 27static void send_from(int fd, int nowild, char *packet, size_t len, 28 union mysockaddr *to, struct all_addr *source, 29 unsigned int iface) 30{ 31 struct msghdr msg; 32 struct iovec iov[1]; 33 union { 34 struct cmsghdr align; /* this ensures alignment */ 35#if defined(HAVE_LINUX_NETWORK) 36 char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; 37#elif defined(IP_SENDSRCADDR) 38 char control[CMSG_SPACE(sizeof(struct in_addr))]; 39#endif 40#ifdef HAVE_IPV6 41 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 42#endif 43 } control_u; 44 45 iov[0].iov_base = packet; 46 iov[0].iov_len = len; 47 48 msg.msg_control = NULL; 49 msg.msg_controllen = 0; 50 msg.msg_flags = 0; 51 msg.msg_name = to; 52 msg.msg_namelen = sa_len(to); 53 msg.msg_iov = iov; 54 msg.msg_iovlen = 1; 55 56 if (!nowild) 57 { 58 struct cmsghdr *cmptr; 59 msg.msg_control = &control_u; 60 msg.msg_controllen = sizeof(control_u); 61 cmptr = CMSG_FIRSTHDR(&msg); 62 63 if (to->sa.sa_family == AF_INET) 64 { 65#if defined(HAVE_LINUX_NETWORK) 66 struct in_pktinfo *pkt = (struct in_pktinfo *)CMSG_DATA(cmptr); 67 pkt->ipi_ifindex = 0; 68 pkt->ipi_spec_dst = source->addr.addr4; 69 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); 70 cmptr->cmsg_level = SOL_IP; 71 cmptr->cmsg_type = IP_PKTINFO; 72#elif defined(IP_SENDSRCADDR) 73 struct in_addr *a = (struct in_addr *)CMSG_DATA(cmptr); 74 *a = source->addr.addr4; 75 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); 76 cmptr->cmsg_level = IPPROTO_IP; 77 cmptr->cmsg_type = IP_SENDSRCADDR; 78#endif 79 } 80 else 81#ifdef HAVE_IPV6 82 { 83 struct in6_pktinfo *pkt = (struct in6_pktinfo *)CMSG_DATA(cmptr); 84 pkt->ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */ 85 pkt->ipi6_addr = source->addr.addr6; 86 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); 87 cmptr->cmsg_type = IPV6_PKTINFO; 88 cmptr->cmsg_level = IPV6_LEVEL; 89 } 90#else 91 iface = 0; /* eliminate warning */ 92#endif 93 } 94 95 retry: 96 if (sendmsg(fd, &msg, 0) == -1) 97 { 98 /* certain Linux kernels seem to object to setting the source address in the IPv6 stack 99 by returning EINVAL from sendmsg. In that case, try again without setting the 100 source address, since it will nearly alway be correct anyway. IPv6 stinks. */ 101 if (errno == EINVAL && msg.msg_controllen) 102 { 103 msg.msg_controllen = 0; 104 goto retry; 105 } 106 if (retry_send()) 107 goto retry; 108 } 109} 110 111static unsigned short search_servers(struct daemon *daemon, time_t now, struct all_addr **addrpp, 112 unsigned short qtype, char *qdomain, int *type, char **domain) 113 114{ 115 /* If the query ends in the domain in one of our servers, set 116 domain to point to that name. We find the largest match to allow both 117 domain.org and sub.domain.org to exist. */ 118 119 unsigned int namelen = strlen(qdomain); 120 unsigned int matchlen = 0; 121 struct server *serv; 122 unsigned short flags = 0; 123 124 for (serv = daemon->servers; serv; serv=serv->next) 125 /* domain matches take priority over NODOTS matches */ 126 if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0) 127 { 128 unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6; 129 *type = SERV_FOR_NODOTS; 130 if (serv->flags & SERV_NO_ADDR) 131 flags = F_NXDOMAIN; 132 else if (serv->flags & SERV_LITERAL_ADDRESS) 133 { 134 if (sflag & qtype) 135 { 136 flags = sflag; 137 if (serv->addr.sa.sa_family == AF_INET) 138 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; 139#ifdef HAVE_IPV6 140 else 141 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; 142#endif 143 } 144 else if (!flags) 145 flags = F_NOERR; 146 } 147 } 148 else if (serv->flags & SERV_HAS_DOMAIN) 149 { 150 unsigned int domainlen = strlen(serv->domain); 151 char *matchstart = qdomain + namelen - domainlen; 152 if (namelen >= domainlen && 153 hostname_isequal(matchstart, serv->domain) && 154 domainlen >= matchlen && 155 (domainlen == 0 || namelen == domainlen || *(serv->domain) == '.' || *(matchstart-1) == '.' )) 156 { 157 unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6; 158 *type = SERV_HAS_DOMAIN; 159 *domain = serv->domain; 160 matchlen = domainlen; 161 if (serv->flags & SERV_NO_ADDR) 162 flags = F_NXDOMAIN; 163 else if (serv->flags & SERV_LITERAL_ADDRESS) 164 { 165 if ((sflag | F_QUERY ) & qtype) 166 { 167 flags = qtype; 168 if (serv->addr.sa.sa_family == AF_INET) 169 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; 170#ifdef HAVE_IPV6 171 else 172 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; 173#endif 174 } 175 else if (!flags) 176 flags = F_NOERR; 177 } 178 } 179 } 180 181 if (flags & ~(F_NOERR | F_NXDOMAIN)) /* flags set here means a literal found */ 182 { 183 if (flags & F_QUERY) 184 log_query(F_CONFIG | F_FORWARD | F_NEG, qdomain, NULL, 0, NULL, 0); 185 else 186 log_query(F_CONFIG | F_FORWARD | flags, qdomain, *addrpp, 0, NULL, 0); 187 } 188 else if (qtype && (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0) 189 flags = F_NXDOMAIN; 190 191 if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now, daemon)) 192 flags = F_NOERR; 193 194 if (flags == F_NXDOMAIN || flags == F_NOERR) 195 log_query(F_CONFIG | F_FORWARD | F_NEG | qtype | (flags & F_NXDOMAIN), qdomain, NULL, 0, NULL, 0); 196 197 return flags; 198} 199 200/* returns new last_server */ 201static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *udpaddr, 202 struct all_addr *dst_addr, unsigned int dst_iface, 203 HEADER *header, size_t plen, time_t now, struct frec *forward) 204{ 205 char *domain = NULL; 206 int type = 0; 207 struct all_addr *addrp = NULL; 208 unsigned int crc = questions_crc(header, plen, daemon->namebuff); 209 unsigned short flags = 0; 210 unsigned short gotname = extract_request(header, plen, daemon->namebuff, NULL); 211 struct server *start = NULL; 212 213 /* may be no servers available. */ 214 if (!daemon->servers) 215 forward = NULL; 216 else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc))) 217 { 218 /* retry on existing query, send to all available servers */ 219 domain = forward->sentto->domain; 220 if (!(daemon->options & OPT_ORDER)) 221 { 222 forward->forwardall = 1; 223 daemon->last_server = NULL; 224 } 225 type = forward->sentto->flags & SERV_TYPE; 226 if (!(start = forward->sentto->next)) 227 start = daemon->servers; /* at end of list, recycle */ 228 header->id = htons(forward->new_id); 229 } 230 else 231 { 232 if (gotname) 233 flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain); 234 235 if (!flags && !(forward = get_new_frec(daemon, now))) 236 /* table full - server failure. */ 237 flags = F_NEG; 238 239 if (forward) 240 { 241 forward->source = *udpaddr; 242 forward->dest = *dst_addr; 243 forward->iface = dst_iface; 244 forward->new_id = get_id(); 245 forward->fd = udpfd; 246 forward->orig_id = ntohs(header->id); 247 forward->crc = crc; 248 forward->forwardall = 0; 249 header->id = htons(forward->new_id); 250 251 /* In strict_order mode, or when using domain specific servers 252 always try servers in the order specified in resolv.conf, 253 otherwise, use the one last known to work. */ 254 255 if (type != 0 || (daemon->options & OPT_ORDER)) 256 start = daemon->servers; 257 else if (!(start = daemon->last_server)) 258 { 259 start = daemon->servers; 260 forward->forwardall = 1; 261 } 262 } 263 } 264 265 /* check for send errors here (no route to host) 266 if we fail to send to all nameservers, send back an error 267 packet straight away (helps modem users when offline) */ 268 269 if (!flags && forward) 270 { 271 struct server *firstsentto = start; 272 int forwarded = 0; 273 274 while (1) 275 { 276 /* only send to servers dealing with our domain. 277 domain may be NULL, in which case server->domain 278 must be NULL also. */ 279 280 if (type == (start->flags & SERV_TYPE) && 281 (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) && 282 !(start->flags & SERV_LITERAL_ADDRESS)) 283 { 284 if (sendto(start->sfd->fd, (char *)header, plen, 0, 285 &start->addr.sa, 286 sa_len(&start->addr)) == -1) 287 { 288 if (retry_send()) 289 continue; 290 } 291 else 292 { 293 /* Keep info in case we want to re-send this packet */ 294 daemon->srv_save = start; 295 daemon->packet_len = plen; 296 297 if (!gotname) 298 strcpy(daemon->namebuff, "query"); 299 if (start->addr.sa.sa_family == AF_INET) 300 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 301 (struct all_addr *)&start->addr.in.sin_addr, 0, 302 NULL, 0); 303#ifdef HAVE_IPV6 304 else 305 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 306 (struct all_addr *)&start->addr.in6.sin6_addr, 0, 307 NULL, 0); 308#endif 309 forwarded = 1; 310 forward->sentto = start; 311 if (!forward->forwardall) 312 break; 313 forward->forwardall++; 314 } 315 } 316 317 if (!(start = start->next)) 318 start = daemon->servers; 319 320 if (start == firstsentto) 321 break; 322 } 323 324 if (forwarded) 325 return; 326 327 /* could not send on, prepare to return */ 328 header->id = htons(forward->orig_id); 329 forward->new_id = 0; /* cancel */ 330 } 331 332 /* could not send on, return empty answer or address if known for whole domain */ 333 if (udpfd != -1) 334 { 335 plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl); 336 send_from(udpfd, daemon->options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface); 337 } 338 339 return; 340} 341 342static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now, 343 unsigned int query_crc, struct server *server, size_t n) 344{ 345 unsigned char *pheader, *sizep; 346 int munged = 0; 347 size_t plen; 348 349 /* If upstream is advertising a larger UDP packet size 350 than we allow, trim it so that we don't get overlarge 351 requests for the client. */ 352 353 if ((pheader = find_pseudoheader(header, n, &plen, &sizep))) 354 { 355 unsigned short udpsz; 356 unsigned char *psave = sizep; 357 358 GETSHORT(udpsz, sizep); 359 if (udpsz > daemon->edns_pktsz) 360 PUTSHORT(daemon->edns_pktsz, psave); 361 } 362 363 if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN)) 364 return n; 365 366 /* Complain loudly if the upstream server is non-recursive. */ 367 if (!header->ra && header->rcode == NOERROR && ntohs(header->ancount) == 0 && 368 server && !(server->flags & SERV_WARNED_RECURSIVE)) 369 { 370 prettyprint_addr(&server->addr, daemon->namebuff); 371 syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff); 372 if (!(daemon->options & OPT_LOG)) 373 server->flags |= SERV_WARNED_RECURSIVE; 374 } 375 376 if (daemon->bogus_addr && header->rcode != NXDOMAIN && 377 check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)) 378 { 379 munged = 1; 380 header->rcode = NXDOMAIN; 381 header->aa = 0; 382 } 383 else 384 { 385 if (header->rcode == NXDOMAIN && 386 extract_request(header, n, daemon->namebuff, NULL) && 387 check_for_local_domain(daemon->namebuff, now, daemon)) 388 { 389 /* if we forwarded a query for a locally known name (because it was for 390 an unknown type) and the answer is NXDOMAIN, convert that to NODATA, 391 since we know that the domain exists, even if upstream doesn't */ 392 munged = 1; 393 header->aa = 1; 394 header->rcode = NOERROR; 395 } 396 397 /* If the crc of the question section doesn't match the crc we sent, then 398 someone might be attempting to insert bogus values into the cache by 399 sending replies containing questions and bogus answers. */ 400 if (query_crc == questions_crc(header, n, daemon->namebuff)) 401 extract_addresses(header, n, daemon->namebuff, now, daemon); 402 } 403 404 /* do this after extract_addresses. Ensure NODATA reply and remove 405 nameserver info. */ 406 407 if (munged) 408 { 409 header->ancount = htons(0); 410 header->nscount = htons(0); 411 header->arcount = htons(0); 412 } 413 414 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide 415 sections of the packet. Find the new length here and put back pseudoheader 416 if it was removed. */ 417 return resize_packet(header, n, pheader, plen); 418} 419 420/* sets new last_server */ 421void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now) 422{ 423 /* packet from peer server, extract data for cache, and send to 424 original requester */ 425 struct frec *forward; 426 HEADER *header; 427 union mysockaddr serveraddr; 428 socklen_t addrlen = sizeof(serveraddr); 429 ssize_t n = recvfrom(sfd->fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen); 430 size_t nn; 431 432 /* packet buffer overwritten */ 433 daemon->srv_save = NULL; 434 435 /* Determine the address of the server replying so that we can mark that as good */ 436 serveraddr.sa.sa_family = sfd->source_addr.sa.sa_family; 437#ifdef HAVE_IPV6 438 if (serveraddr.sa.sa_family == AF_INET6) 439 serveraddr.in6.sin6_flowinfo = 0; 440#endif 441 442 header = (HEADER *)daemon->packet; 443 forward = lookup_frec(ntohs(header->id)); 444 445 if (n >= (int)sizeof(HEADER) && header->qr && forward) 446 { 447 struct server *server = forward->sentto; 448 449 if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0) 450 /* for broken servers, attempt to send to another one. */ 451 { 452 unsigned char *pheader; 453 size_t plen; 454 455 /* recreate query from reply */ 456 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL); 457 header->ancount = htons(0); 458 header->nscount = htons(0); 459 header->arcount = htons(0); 460 if ((nn = resize_packet(header, (size_t)n, pheader, plen))) 461 { 462 forward->forwardall = 1; 463 header->qr = 0; 464 header->tc = 0; 465 forward_query(daemon, -1, NULL, NULL, 0, header, nn, now, forward); 466 return; 467 } 468 } 469 470 if ((forward->sentto->flags & SERV_TYPE) == 0) 471 { 472 if (header->rcode == SERVFAIL || header->rcode == REFUSED) 473 server = NULL; 474 else 475 { 476 struct server *last_server; 477 /* find good server by address if possible, otherwise assume the last one we sent to */ 478 for (last_server = daemon->servers; last_server; last_server = last_server->next) 479 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) && 480 sockaddr_isequal(&last_server->addr, &serveraddr)) 481 { 482 server = last_server; 483 break; 484 } 485 } 486 daemon->last_server = server; 487 } 488 489 /* If the answer is an error, keep the forward record in place in case 490 we get a good reply from another server. Kill it when we've 491 had replies from all to avoid filling the forwarding table when 492 everything is broken */ 493 if (forward->forwardall == 0 || --forward->forwardall == 1 || 494 (header->rcode != REFUSED && header->rcode != SERVFAIL)) 495 { 496 if ((nn = process_reply(daemon, header, now, forward->crc, server, (size_t)n))) 497 { 498 header->id = htons(forward->orig_id); 499 header->ra = 1; /* recursion if available */ 500 send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn, 501 &forward->source, &forward->dest, forward->iface); 502 } 503 forward->new_id = 0; /* cancel */ 504 } 505 } 506} 507 508void receive_query(struct listener *listen, struct daemon *daemon, time_t now) 509{ 510 HEADER *header = (HEADER *)daemon->packet; 511 union mysockaddr source_addr; 512 unsigned short type; 513 struct all_addr dst_addr; 514 struct in_addr netmask, dst_addr_4; 515 size_t m; 516 ssize_t n; 517 int if_index = 0; 518 struct iovec iov[1]; 519 struct msghdr msg; 520 struct cmsghdr *cmptr; 521 union { 522 struct cmsghdr align; /* this ensures alignment */ 523#ifdef HAVE_IPV6 524 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; 525#endif 526#if defined(HAVE_LINUX_NETWORK) 527 char control[CMSG_SPACE(sizeof(struct in_pktinfo))]; 528#elif defined(IP_RECVDSTADDR) 529 char control[CMSG_SPACE(sizeof(struct in_addr)) + 530 CMSG_SPACE(sizeof(struct sockaddr_dl))]; 531#endif 532 } control_u; 533 534 /* packet buffer overwritten */ 535 daemon->srv_save = NULL; 536 537 if (listen->family == AF_INET && (daemon->options & OPT_NOWILD)) 538 { 539 dst_addr_4 = listen->iface->addr.in.sin_addr; 540 netmask = listen->iface->netmask; 541 } 542 else 543 { 544 dst_addr_4.s_addr = 0; 545 netmask.s_addr = 0; 546 } 547 548 iov[0].iov_base = daemon->packet; 549 iov[0].iov_len = daemon->edns_pktsz; 550 551 msg.msg_control = control_u.control; 552 msg.msg_controllen = sizeof(control_u); 553 msg.msg_flags = 0; 554 msg.msg_name = &source_addr; 555 msg.msg_namelen = sizeof(source_addr); 556 msg.msg_iov = iov; 557 msg.msg_iovlen = 1; 558 559 if ((n = recvmsg(listen->fd, &msg, 0)) == -1) 560 return; 561 562 if (n < (int)sizeof(HEADER) || 563 (msg.msg_flags & MSG_TRUNC) || 564 header->qr) 565 return; 566 567 source_addr.sa.sa_family = listen->family; 568#ifdef HAVE_IPV6 569 if (listen->family == AF_INET6) 570 source_addr.in6.sin6_flowinfo = 0; 571#endif 572 573 if (!(daemon->options & OPT_NOWILD)) 574 { 575 struct ifreq ifr; 576 577 if (msg.msg_controllen < sizeof(struct cmsghdr)) 578 return; 579 580#if defined(HAVE_LINUX_NETWORK) 581 if (listen->family == AF_INET) 582 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 583 if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO) 584 { 585 dst_addr_4 = dst_addr.addr.addr4 = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_spec_dst; 586 if_index = ((struct in_pktinfo *)CMSG_DATA(cmptr))->ipi_ifindex; 587 } 588#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) 589 if (listen->family == AF_INET) 590 { 591 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 592 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR) 593 dst_addr_4 = dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr)); 594 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) 595 if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index; 596 } 597#endif 598 599#ifdef HAVE_IPV6 600 if (listen->family == AF_INET6) 601 { 602 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr)) 603 if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == IPV6_PKTINFO) 604 { 605 dst_addr.addr.addr6 = ((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_addr; 606 if_index =((struct in6_pktinfo *)CMSG_DATA(cmptr))->ipi6_ifindex; 607 } 608 } 609#endif 610 611 /* enforce available interface configuration */ 612 613 if (if_index == 0) 614 return; 615 616 if (daemon->if_except || daemon->if_names || (daemon->options & OPT_LOCALISE)) 617 { 618#ifdef SIOCGIFNAME 619 ifr.ifr_ifindex = if_index; 620 if (ioctl(listen->fd, SIOCGIFNAME, &ifr) == -1) 621 return; 622#else 623 if (!if_indextoname(if_index, ifr.ifr_name)) 624 return; 625#endif 626 627 if (listen->family == AF_INET && 628 (daemon->options & OPT_LOCALISE) && 629 ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1) 630 return; 631 632 netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; 633 } 634 635 if (!iface_check(daemon, listen->family, &dst_addr, ifr.ifr_name)) 636 return; 637 } 638 639 if (extract_request(header, (size_t)n, daemon->namebuff, &type)) 640 { 641 if (listen->family == AF_INET) 642 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 643 (struct all_addr *)&source_addr.in.sin_addr, type, NULL, 0); 644#ifdef HAVE_IPV6 645 else 646 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 647 (struct all_addr *)&source_addr.in6.sin6_addr, type, NULL, 0); 648#endif 649 } 650 651 m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n, daemon, 652 dst_addr_4, netmask, now); 653 if (m >= 1) 654 send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header, m, &source_addr, &dst_addr, if_index); 655 else 656 forward_query(daemon, listen->fd, &source_addr, &dst_addr, if_index, 657 header, (size_t)n, now, NULL); 658} 659 660static int read_write(int fd, unsigned char *packet, int size, int rw) 661{ 662 ssize_t n, done; 663 664 for (done = 0; done < size; done += n) 665 { 666 retry: 667 if (rw) 668 n = read(fd, &packet[done], (size_t)(size - done)); 669 else 670 n = write(fd, &packet[done], (size_t)(size - done)); 671 672 if (n == 0) 673 return 0; 674 else if (n == -1) 675 { 676 if (errno == EINTR) 677 goto retry; 678 else 679 return 0; 680 } 681 } 682 return 1; 683} 684 685/* The daemon forks before calling this: it should deal with one connection, 686 blocking as neccessary, and then return. Note, need to be a bit careful 687 about resources for debug mode, when the fork is suppressed: that's 688 done by the caller. */ 689unsigned char *tcp_request(struct daemon *daemon, int confd, time_t now, 690 struct in_addr local_addr, struct in_addr netmask) 691{ 692 int size = 0; 693 size_t m; 694 unsigned short qtype, gotname; 695 unsigned char c1, c2; 696 /* Max TCP packet + slop */ 697 unsigned char *packet = malloc(65536 + MAXDNAME + RRFIXEDSZ); 698 HEADER *header; 699 struct server *last_server; 700 701 while (1) 702 { 703 if (!packet || 704 !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) || 705 !(size = c1 << 8 | c2) || 706 !read_write(confd, packet, size, 1)) 707 return packet; 708 709 if (size < (int)sizeof(HEADER)) 710 continue; 711 712 header = (HEADER *)packet; 713 714 if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype))) 715 { 716 union mysockaddr peer_addr; 717 socklen_t peer_len = sizeof(union mysockaddr); 718 719 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1) 720 { 721 if (peer_addr.sa.sa_family == AF_INET) 722 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 723 (struct all_addr *)&peer_addr.in.sin_addr, qtype, NULL, 0); 724#ifdef HAVE_IPV6 725 else 726 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 727 (struct all_addr *)&peer_addr.in6.sin6_addr, qtype, NULL, 0); 728#endif 729 } 730 } 731 732 /* m > 0 if answered from cache */ 733 m = answer_request(header, ((char *) header) + 65536, (unsigned int)size, daemon, 734 local_addr, netmask, now); 735 736 if (m == 0) 737 { 738 unsigned short flags = 0; 739 struct all_addr *addrp = NULL; 740 int type = 0; 741 char *domain = NULL; 742 743 if (gotname) 744 flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain); 745 746 if (type != 0 || (daemon->options & OPT_ORDER) || !daemon->last_server) 747 last_server = daemon->servers; 748 else 749 last_server = daemon->last_server; 750 751 if (!flags && last_server) 752 { 753 struct server *firstsendto = NULL; 754 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff); 755 756 /* Loop round available servers until we succeed in connecting to one. 757 Note that this code subtley ensures that consecutive queries on this connection 758 which can go to the same server, do so. */ 759 while (1) 760 { 761 if (!firstsendto) 762 firstsendto = last_server; 763 else 764 { 765 if (!(last_server = last_server->next)) 766 last_server = daemon->servers; 767 768 if (last_server == firstsendto) 769 break; 770 } 771 772 /* server for wrong domain */ 773 if (type != (last_server->flags & SERV_TYPE) || 774 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain))) 775 continue; 776 777 if ((last_server->tcpfd == -1) && 778 (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 && 779 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1) 780 { 781 close(last_server->tcpfd); 782 last_server->tcpfd = -1; 783 } 784 785 if (last_server->tcpfd == -1) 786 continue; 787 788 c1 = size >> 8; 789 c2 = size; 790 791 if (!read_write(last_server->tcpfd, &c1, 1, 0) || 792 !read_write(last_server->tcpfd, &c2, 1, 0) || 793 !read_write(last_server->tcpfd, packet, size, 0) || 794 !read_write(last_server->tcpfd, &c1, 1, 1) || 795 !read_write(last_server->tcpfd, &c2, 1, 1)) 796 { 797 close(last_server->tcpfd); 798 last_server->tcpfd = -1; 799 continue; 800 } 801 802 m = (c1 << 8) | c2; 803 if (!read_write(last_server->tcpfd, packet, m, 1)) 804 return packet; 805 806 if (!gotname) 807 strcpy(daemon->namebuff, "query"); 808 if (last_server->addr.sa.sa_family == AF_INET) 809 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 810 (struct all_addr *)&last_server->addr.in.sin_addr, 0, NULL, 0); 811#ifdef HAVE_IPV6 812 else 813 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 814 (struct all_addr *)&last_server->addr.in6.sin6_addr, 0, NULL, 0); 815#endif 816 817 /* There's no point in updating the cache, since this process will exit and 818 lose the information after one query. We make this call for the alias and 819 bogus-nxdomain side-effects. */ 820 m = process_reply(daemon, header, now, crc, last_server, (unsigned int)m); 821 822 break; 823 } 824 } 825 826 /* In case of local answer or no connections made. */ 827 if (m == 0) 828 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl); 829 } 830 831 c1 = m>>8; 832 c2 = m; 833 if (!read_write(confd, &c1, 1, 0) || 834 !read_write(confd, &c2, 1, 0) || 835 !read_write(confd, packet, m, 0)) 836 return packet; 837 } 838} 839 840static struct frec *get_new_frec(struct daemon *daemon, time_t now) 841{ 842 struct frec *f = frec_list, *oldest = NULL; 843 time_t oldtime = now; 844 int count = 0; 845 static time_t warntime = 0; 846 847 while (f) 848 { 849 if (f->new_id == 0) 850 { 851 f->time = now; 852 return f; 853 } 854 855 if (difftime(f->time, oldtime) <= 0) 856 { 857 oldtime = f->time; 858 oldest = f; 859 } 860 861 count++; 862 f = f->next; 863 } 864 865 /* can't find empty one, use oldest if there is one 866 and it's older than timeout */ 867 if (oldest && difftime(now, oldtime) > TIMEOUT) 868 { 869 oldest->time = now; 870 return oldest; 871 } 872 873 if (count > daemon->ftabsize) 874 { /* limit logging rate so syslog isn't DOSed either */ 875 if (!warntime || difftime(now, warntime) > LOGRATE) 876 { 877 warntime = now; 878 syslog(LOG_WARNING, _("forwarding table overflow: check for server loops.")); 879 } 880 return NULL; 881 } 882 883 if ((f = (struct frec *)malloc(sizeof(struct frec)))) 884 { 885 f->next = frec_list; 886 f->time = now; 887 f->new_id = 0; 888 frec_list = f; 889 } 890 return f; /* OK if malloc fails and this is NULL */ 891} 892 893static struct frec *lookup_frec(unsigned short id) 894{ 895 struct frec *f; 896 897 for(f = frec_list; f; f = f->next) 898 if (f->new_id == id) 899 return f; 900 901 return NULL; 902} 903 904static struct frec *lookup_frec_by_sender(unsigned short id, 905 union mysockaddr *addr, 906 unsigned int crc) 907{ 908 struct frec *f; 909 910 for(f = frec_list; f; f = f->next) 911 if (f->new_id && 912 f->orig_id == id && 913 f->crc == crc && 914 sockaddr_isequal(&f->source, addr)) 915 return f; 916 917 return NULL; 918} 919 920/* A server record is going away, remove references to it */ 921void server_gone(struct daemon *daemon, struct server *server) 922{ 923 struct frec *f; 924 925 for (f = frec_list; f; f = f->next) 926 if (f->new_id != 0 && f->sentto == server) 927 f->new_id = 0; 928 929 if (daemon->last_server == server) 930 daemon->last_server = NULL; 931 932 if (daemon->srv_save == server) 933 daemon->srv_save = NULL; 934} 935 936/* return unique random ids between 1 and 65535 */ 937static unsigned short get_id(void) 938{ 939 unsigned short ret = 0; 940 941 while (ret == 0) 942 { 943 ret = rand16(); 944 945 /* scrap ids already in use */ 946 if ((ret != 0) && lookup_frec(ret)) 947 ret = 0; 948 } 949 950 return ret; 951} 952 953 954 955 956 957