]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/forward.c
import of dnsmasq-2.40.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
5aabfc78 110static unsigned short search_servers(time_t now, struct all_addr **addrpp,
36717eee 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
5aabfc78 192 if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
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 */
5aabfc78 202static void forward_query(int udpfd, union mysockaddr *udpaddr,
3be34541 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)
5aabfc78 234 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
9e4abcb5 235
5aabfc78 236 if (!flags && !(forward = get_new_frec(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
5aabfc78 347static size_t process_reply(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);
f2621c7f 376 my_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) &&
5aabfc78 392 check_for_local_domain(daemon->namebuff, now))
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 401
5aabfc78 402 extract_addresses(header, n, daemon->namebuff, now);
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 421/* sets new last_server */
5aabfc78 422void reply_query(struct serverfd *sfd, 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;
5aabfc78 470 forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
832af0ba
SK
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 {
5aabfc78 502 if ((nn = process_reply(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
5aabfc78 514void receive_query(struct listener *listen, 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 630
5aabfc78 631 if (!iface_check(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
5aabfc78 654 m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n,
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
5aabfc78 659 forward_query(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. */
5aabfc78 667unsigned char *tcp_request(int confd, time_t now,
3d8df260 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 */
5aabfc78 675 unsigned char *packet = whine_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 */
5aabfc78 711 m = answer_request(header, ((char *) header) + 65536, (unsigned int)size,
f6b7dc47 712 local_addr, netmask, now);
5aabfc78
SK
713
714 /* Do this by steam now we're not in the select() loop */
715 check_log_writer(NULL);
feba5c1d
SK
716
717 if (m == 0)
718 {
719 unsigned short flags = 0;
feba5c1d
SK
720 struct all_addr *addrp = NULL;
721 int type = 0;
722 char *domain = NULL;
723
724 if (gotname)
5aabfc78 725 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
feba5c1d 726
3be34541
SK
727 if (type != 0 || (daemon->options & OPT_ORDER) || !daemon->last_server)
728 last_server = daemon->servers;
729 else
730 last_server = daemon->last_server;
feba5c1d
SK
731
732 if (!flags && last_server)
733 {
734 struct server *firstsendto = NULL;
0a852541
SK
735 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
736
feba5c1d
SK
737 /* Loop round available servers until we succeed in connecting to one.
738 Note that this code subtley ensures that consecutive queries on this connection
739 which can go to the same server, do so. */
740 while (1)
741 {
742 if (!firstsendto)
743 firstsendto = last_server;
744 else
745 {
746 if (!(last_server = last_server->next))
3be34541 747 last_server = daemon->servers;
feba5c1d
SK
748
749 if (last_server == firstsendto)
750 break;
751 }
752
753 /* server for wrong domain */
754 if (type != (last_server->flags & SERV_TYPE) ||
755 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
756 continue;
757
758 if ((last_server->tcpfd == -1) &&
759 (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
760 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1)
761 {
762 close(last_server->tcpfd);
763 last_server->tcpfd = -1;
764 }
765
766 if (last_server->tcpfd == -1)
767 continue;
768
769 c1 = size >> 8;
770 c2 = size;
771
772 if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
773 !read_write(last_server->tcpfd, &c2, 1, 0) ||
774 !read_write(last_server->tcpfd, packet, size, 0) ||
775 !read_write(last_server->tcpfd, &c1, 1, 1) ||
776 !read_write(last_server->tcpfd, &c2, 1, 1))
777 {
778 close(last_server->tcpfd);
779 last_server->tcpfd = -1;
780 continue;
781 }
782
783 m = (c1 << 8) | c2;
784 if (!read_write(last_server->tcpfd, packet, m, 1))
785 return packet;
786
787 if (!gotname)
3be34541 788 strcpy(daemon->namebuff, "query");
feba5c1d 789 if (last_server->addr.sa.sa_family == AF_INET)
3be34541 790 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
fd9fa481 791 (struct all_addr *)&last_server->addr.in.sin_addr, 0, NULL, 0);
feba5c1d
SK
792#ifdef HAVE_IPV6
793 else
3be34541 794 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
fd9fa481 795 (struct all_addr *)&last_server->addr.in6.sin6_addr, 0, NULL, 0);
feba5c1d
SK
796#endif
797
798 /* There's no point in updating the cache, since this process will exit and
832af0ba 799 lose the information after a few queries. We make this call for the alias and
feba5c1d 800 bogus-nxdomain side-effects. */
832af0ba
SK
801 /* If the crc of the question section doesn't match the crc we sent, then
802 someone might be attempting to insert bogus values into the cache by
803 sending replies containing questions and bogus answers. */
804 if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
5aabfc78 805 m = process_reply(header, now, last_server, (unsigned int)m);
feba5c1d
SK
806
807 break;
808 }
809 }
810
811 /* In case of local answer or no connections made. */
812 if (m == 0)
3be34541 813 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
feba5c1d 814 }
5aabfc78
SK
815
816 check_log_writer(NULL);
feba5c1d
SK
817
818 c1 = m>>8;
819 c2 = m;
820 if (!read_write(confd, &c1, 1, 0) ||
821 !read_write(confd, &c2, 1, 0) ||
822 !read_write(confd, packet, m, 0))
823 return packet;
824 }
825}
826
1697269c 827static struct frec *allocate_frec(time_t now)
9e4abcb5 828{
1697269c
SK
829 struct frec *f;
830
5aabfc78 831 if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
9e4abcb5 832 {
1697269c
SK
833 f->next = frec_list;
834 f->time = now;
832af0ba 835 f->sentto = NULL;
1697269c
SK
836 frec_list = f;
837 }
9e4abcb5 838
1697269c
SK
839 return f;
840}
9e4abcb5 841
1697269c
SK
842/* if wait==NULL return a free or older than TIMEOUT record.
843 else return *wait zero if one available, or *wait is delay to
844 when the oldest in-use record will expire. */
5aabfc78 845struct frec *get_new_frec(time_t now, int *wait)
1697269c
SK
846{
847 struct frec *f, *oldest;
848 int count;
849
850 if (wait)
851 *wait = 0;
852
853 for (f = frec_list, oldest = NULL, count = 0; f; f = f->next, count++)
832af0ba 854 if (!f->sentto)
1697269c
SK
855 {
856 f->time = now;
857 return f;
858 }
859 else if (!oldest || difftime(f->time, oldest->time) <= 0)
860 oldest = f;
9e4abcb5
SK
861
862 /* can't find empty one, use oldest if there is one
863 and it's older than timeout */
1697269c 864 if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
9e4abcb5 865 {
1697269c
SK
866 /* keep stuff for twice timeout if we can by allocating a new
867 record instead */
868 if (difftime(now, oldest->time) < 2*TIMEOUT &&
869 count <= daemon->ftabsize &&
870 (f = allocate_frec(now)))
871 return f;
872
873 if (!wait)
874 {
832af0ba 875 oldest->sentto = 0;
1697269c
SK
876 oldest->time = now;
877 }
9e4abcb5
SK
878 return oldest;
879 }
880
1697269c 881 /* none available, calculate time 'till oldest record expires */
208b65c5 882 if (count > daemon->ftabsize)
1697269c
SK
883 {
884 if (oldest && wait)
885 *wait = oldest->time + (time_t)TIMEOUT - now;
9e4abcb5
SK
886 return NULL;
887 }
1697269c
SK
888
889 if (!(f = allocate_frec(now)) && wait)
890 /* wait one second on malloc failure */
891 *wait = 1;
9e4abcb5 892
9e4abcb5
SK
893 return f; /* OK if malloc fails and this is NULL */
894}
895
832af0ba
SK
896/* crc is all-ones if not known. */
897static struct frec *lookup_frec(unsigned short id, unsigned int crc)
9e4abcb5
SK
898{
899 struct frec *f;
900
901 for(f = frec_list; f; f = f->next)
832af0ba
SK
902 if (f->sentto && f->new_id == id &&
903 (f->crc == crc || crc == 0xffffffff))
9e4abcb5
SK
904 return f;
905
906 return NULL;
907}
908
909static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481
SK
910 union mysockaddr *addr,
911 unsigned int crc)
9e4abcb5 912{
feba5c1d
SK
913 struct frec *f;
914
9e4abcb5 915 for(f = frec_list; f; f = f->next)
832af0ba 916 if (f->sentto &&
9e4abcb5 917 f->orig_id == id &&
fd9fa481 918 f->crc == crc &&
9e4abcb5
SK
919 sockaddr_isequal(&f->source, addr))
920 return f;
921
922 return NULL;
923}
924
849a8357 925/* A server record is going away, remove references to it */
5aabfc78 926void server_gone(struct server *server)
849a8357
SK
927{
928 struct frec *f;
929
930 for (f = frec_list; f; f = f->next)
832af0ba
SK
931 if (f->sentto && f->sentto == server)
932 f->sentto = NULL;
849a8357
SK
933
934 if (daemon->last_server == server)
935 daemon->last_server = NULL;
936
937 if (daemon->srv_save == server)
938 daemon->srv_save = NULL;
939}
9e4abcb5 940
832af0ba
SK
941/* return unique random ids.
942 For signed packets we can't change the ID without breaking the
943 signing, so we keep the same one. In this case force is set, and this
944 routine degenerates into killing any conflicting forward record. */
945static unsigned short get_id(int force, unsigned short force_id, unsigned int crc)
9e4abcb5
SK
946{
947 unsigned short ret = 0;
832af0ba
SK
948
949 if (force)
9e4abcb5 950 {
832af0ba
SK
951 struct frec *f = lookup_frec(force_id, crc);
952 if (f)
953 f->sentto = NULL; /* free */
954 ret = force_id;
9e4abcb5 955 }
832af0ba
SK
956 else do
957 ret = rand16();
958 while (lookup_frec(ret, crc));
959
9e4abcb5
SK
960 return ret;
961}
962
963
964
965
966