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