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