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