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