]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/forward.c
Fix wrong DNSMASQ_LEASE_EXPIRES envar when luascript in use also.
[people/ms/dnsmasq.git] / src / forward.c
CommitLineData
61744359 1/* dnsmasq is Copyright (c) 2000-2013 Simon Kelley
9e4abcb5
SK
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
824af85b
SK
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
9e4abcb5
SK
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
824af85b 12
73a08a24
SK
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
9e4abcb5
SK
15*/
16
9e4abcb5
SK
17#include "dnsmasq.h"
18
832af0ba 19static struct frec *lookup_frec(unsigned short id, unsigned int crc);
9e4abcb5 20static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481
SK
21 union mysockaddr *addr,
22 unsigned int crc);
316e2730 23static unsigned short get_id(unsigned int crc);
1a6bca81
SK
24static void free_frec(struct frec *f);
25static struct randfd *allocate_rfd(int family);
9e4abcb5 26
824af85b 27/* Send a UDP packet with its source address set as "source"
44a2a316 28 unless nowild is true, when we just send it with the kernel default */
29689cfa
SK
29int send_from(int fd, int nowild, char *packet, size_t len,
30 union mysockaddr *to, struct all_addr *source,
50303b19 31 unsigned int iface)
9e4abcb5 32{
44a2a316
SK
33 struct msghdr msg;
34 struct iovec iov[1];
44a2a316
SK
35 union {
36 struct cmsghdr align; /* this ensures alignment */
5e9e0efb 37#if defined(HAVE_LINUX_NETWORK)
44a2a316
SK
38 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
39#elif defined(IP_SENDSRCADDR)
40 char control[CMSG_SPACE(sizeof(struct in_addr))];
41#endif
42#ifdef HAVE_IPV6
43 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
44#endif
45 } control_u;
feba5c1d 46
44a2a316
SK
47 iov[0].iov_base = packet;
48 iov[0].iov_len = len;
49
feba5c1d
SK
50 msg.msg_control = NULL;
51 msg.msg_controllen = 0;
44a2a316
SK
52 msg.msg_flags = 0;
53 msg.msg_name = to;
54 msg.msg_namelen = sa_len(to);
55 msg.msg_iov = iov;
56 msg.msg_iovlen = 1;
feba5c1d 57
26128d27 58 if (!nowild)
44a2a316 59 {
26128d27 60 struct cmsghdr *cmptr;
feba5c1d
SK
61 msg.msg_control = &control_u;
62 msg.msg_controllen = sizeof(control_u);
26128d27
SK
63 cmptr = CMSG_FIRSTHDR(&msg);
64
65 if (to->sa.sa_family == AF_INET)
66 {
5e9e0efb 67#if defined(HAVE_LINUX_NETWORK)
8ef5ada2
SK
68 struct in_pktinfo p;
69 p.ipi_ifindex = 0;
70 p.ipi_spec_dst = source->addr.addr4;
71 memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
26128d27 72 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
c72daea8 73 cmptr->cmsg_level = IPPROTO_IP;
26128d27 74 cmptr->cmsg_type = IP_PKTINFO;
44a2a316 75#elif defined(IP_SENDSRCADDR)
8ef5ada2 76 memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4));
26128d27
SK
77 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
78 cmptr->cmsg_level = IPPROTO_IP;
79 cmptr->cmsg_type = IP_SENDSRCADDR;
44a2a316 80#endif
26128d27 81 }
26128d27 82 else
b8187c80 83#ifdef HAVE_IPV6
26128d27 84 {
8ef5ada2
SK
85 struct in6_pktinfo p;
86 p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
87 p.ipi6_addr = source->addr.addr6;
88 memcpy(CMSG_DATA(cmptr), &p, sizeof(p));
26128d27 89 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
316e2730 90 cmptr->cmsg_type = daemon->v6pktinfo;
c72daea8 91 cmptr->cmsg_level = IPPROTO_IPV6;
26128d27 92 }
3d8df260 93#else
c72daea8 94 (void)iface; /* eliminate warning */
44a2a316 95#endif
26128d27 96 }
feba5c1d 97
29d28dda 98 while (sendmsg(fd, &msg, 0) == -1)
feba5c1d 99 {
fd9fa481 100 if (retry_send())
29d28dda 101 continue;
22d904db 102
29d28dda
SK
103 /* If interface is still in DAD, EINVAL results - ignore that. */
104 if (errno == EINVAL)
105 break;
29689cfa 106
29d28dda 107 my_syslog(LOG_ERR, _("failed to send packet: %s"), strerror(errno));
29689cfa 108 return 0;
feba5c1d 109 }
29d28dda 110
29689cfa 111 return 1;
9e4abcb5 112}
44a2a316 113
28866e95
SK
114static unsigned int search_servers(time_t now, struct all_addr **addrpp,
115 unsigned int qtype, char *qdomain, int *type, char **domain, int *norebind)
feba5c1d
SK
116
117{
118 /* If the query ends in the domain in one of our servers, set
119 domain to point to that name. We find the largest match to allow both
120 domain.org and sub.domain.org to exist. */
121
122 unsigned int namelen = strlen(qdomain);
123 unsigned int matchlen = 0;
124 struct server *serv;
28866e95 125 unsigned int flags = 0;
feba5c1d 126
3be34541 127 for (serv = daemon->servers; serv; serv=serv->next)
feba5c1d 128 /* domain matches take priority over NODOTS matches */
3d8df260 129 if ((serv->flags & SERV_FOR_NODOTS) && *type != SERV_HAS_DOMAIN && !strchr(qdomain, '.') && namelen != 0)
feba5c1d 130 {
28866e95 131 unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
feba5c1d 132 *type = SERV_FOR_NODOTS;
feba5c1d 133 if (serv->flags & SERV_NO_ADDR)
36717eee
SK
134 flags = F_NXDOMAIN;
135 else if (serv->flags & SERV_LITERAL_ADDRESS)
136 {
137 if (sflag & qtype)
138 {
139 flags = sflag;
140 if (serv->addr.sa.sa_family == AF_INET)
141 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
feba5c1d 142#ifdef HAVE_IPV6
36717eee
SK
143 else
144 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
feba5c1d 145#endif
36717eee 146 }
824af85b 147 else if (!flags || (flags & F_NXDOMAIN))
36717eee
SK
148 flags = F_NOERR;
149 }
feba5c1d
SK
150 }
151 else if (serv->flags & SERV_HAS_DOMAIN)
152 {
153 unsigned int domainlen = strlen(serv->domain);
b8187c80 154 char *matchstart = qdomain + namelen - domainlen;
feba5c1d 155 if (namelen >= domainlen &&
b8187c80 156 hostname_isequal(matchstart, serv->domain) &&
8ef5ada2 157 (domainlen == 0 || namelen == domainlen || *(matchstart-1) == '.' ))
feba5c1d 158 {
8ef5ada2
SK
159 if (serv->flags & SERV_NO_REBIND)
160 *norebind = 1;
28866e95 161 else
feba5c1d 162 {
28866e95
SK
163 unsigned int sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
164 /* implement priority rules for --address and --server for same domain.
165 --address wins if the address is for the correct AF
166 --server wins otherwise. */
167 if (domainlen != 0 && domainlen == matchlen)
36717eee 168 {
28866e95 169 if ((serv->flags & SERV_LITERAL_ADDRESS))
8ef5ada2 170 {
28866e95
SK
171 if (!(sflag & qtype) && flags == 0)
172 continue;
173 }
174 else
175 {
176 if (flags & (F_IPV4 | F_IPV6))
177 continue;
178 }
179 }
180
181 if (domainlen >= matchlen)
182 {
183 *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND);
184 *domain = serv->domain;
185 matchlen = domainlen;
186 if (serv->flags & SERV_NO_ADDR)
187 flags = F_NXDOMAIN;
188 else if (serv->flags & SERV_LITERAL_ADDRESS)
189 {
190 if (sflag & qtype)
191 {
192 flags = sflag;
193 if (serv->addr.sa.sa_family == AF_INET)
194 *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
feba5c1d 195#ifdef HAVE_IPV6
28866e95
SK
196 else
197 *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
feba5c1d 198#endif
28866e95
SK
199 }
200 else if (!flags || (flags & F_NXDOMAIN))
201 flags = F_NOERR;
8ef5ada2 202 }
28866e95
SK
203 else
204 flags = 0;
205 }
206 }
8ef5ada2 207 }
feba5c1d 208 }
8ef5ada2 209
7de060b0 210 if (flags == 0 && !(qtype & F_QUERY) &&
28866e95 211 option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
7de060b0
SK
212 /* don't forward A or AAAA queries for simple names, except the empty name */
213 flags = F_NOERR;
8ef5ada2 214
5aabfc78 215 if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
c1bb8504 216 flags = F_NOERR;
feba5c1d 217
824af85b
SK
218 if (flags)
219 {
220 int logflags = 0;
221
222 if (flags == F_NXDOMAIN || flags == F_NOERR)
223 logflags = F_NEG | qtype;
224
1a6bca81 225 log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
824af85b 226 }
8ef5ada2
SK
227 else if ((*type) & SERV_USE_RESOLV)
228 {
229 *type = 0; /* use normal servers for this domain */
230 *domain = NULL;
231 }
feba5c1d
SK
232 return flags;
233}
44a2a316 234
824af85b
SK
235static int forward_query(int udpfd, union mysockaddr *udpaddr,
236 struct all_addr *dst_addr, unsigned int dst_iface,
572b41eb 237 struct dns_header *header, size_t plen, time_t now, struct frec *forward)
9e4abcb5 238{
9e4abcb5 239 char *domain = NULL;
8ef5ada2 240 int type = 0, norebind = 0;
9e4abcb5 241 struct all_addr *addrp = NULL;
cdeda28f 242 unsigned int crc = questions_crc(header, plen, daemon->namebuff);
28866e95
SK
243 unsigned int flags = 0;
244 unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
de37951c 245 struct server *start = NULL;
7de060b0 246
28866e95 247 /* RFC 4035: sect 4.6 para 2 */
572b41eb
SK
248 header->hb4 &= ~HB4_AD;
249
3d8df260
SK
250 /* may be no servers available. */
251 if (!daemon->servers)
9e4abcb5 252 forward = NULL;
b8187c80 253 else if (forward || (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, crc)))
9e4abcb5 254 {
de37951c 255 /* retry on existing query, send to all available servers */
9e4abcb5 256 domain = forward->sentto->domain;
824af85b 257 forward->sentto->failed_queries++;
28866e95 258 if (!option_bool(OPT_ORDER))
de37951c 259 {
0a852541 260 forward->forwardall = 1;
3be34541 261 daemon->last_server = NULL;
de37951c 262 }
9e4abcb5 263 type = forward->sentto->flags & SERV_TYPE;
de37951c 264 if (!(start = forward->sentto->next))
3be34541 265 start = daemon->servers; /* at end of list, recycle */
9e4abcb5
SK
266 header->id = htons(forward->new_id);
267 }
268 else
269 {
270 if (gotname)
8ef5ada2 271 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
9e4abcb5 272
5aabfc78 273 if (!flags && !(forward = get_new_frec(now, NULL)))
feba5c1d
SK
274 /* table full - server failure. */
275 flags = F_NEG;
9e4abcb5
SK
276
277 if (forward)
278 {
0a852541
SK
279 forward->source = *udpaddr;
280 forward->dest = *dst_addr;
281 forward->iface = dst_iface;
0a852541 282 forward->orig_id = ntohs(header->id);
316e2730 283 forward->new_id = get_id(crc);
832af0ba 284 forward->fd = udpfd;
0a852541
SK
285 forward->crc = crc;
286 forward->forwardall = 0;
28866e95
SK
287 if (norebind)
288 forward->flags |= FREC_NOREBIND;
572b41eb 289 if (header->hb4 & HB4_CD)
28866e95 290 forward->flags |= FREC_CHECKING_DISABLED;
0a852541 291
28866e95
SK
292 header->id = htons(forward->new_id);
293
8ef5ada2
SK
294 /* In strict_order mode, always try servers in the order
295 specified in resolv.conf, if a domain is given
296 always try all the available servers,
9e4abcb5
SK
297 otherwise, use the one last known to work. */
298
8ef5ada2
SK
299 if (type == 0)
300 {
28866e95 301 if (option_bool(OPT_ORDER))
8ef5ada2
SK
302 start = daemon->servers;
303 else if (!(start = daemon->last_server) ||
304 daemon->forwardcount++ > FORWARD_TEST ||
305 difftime(now, daemon->forwardtime) > FORWARD_TIME)
306 {
307 start = daemon->servers;
308 forward->forwardall = 1;
309 daemon->forwardcount = 0;
310 daemon->forwardtime = now;
311 }
312 }
313 else
de37951c 314 {
3be34541 315 start = daemon->servers;
28866e95 316 if (!option_bool(OPT_ORDER))
8ef5ada2 317 forward->forwardall = 1;
de37951c 318 }
9e4abcb5
SK
319 }
320 }
feba5c1d 321
9e4abcb5
SK
322 /* check for send errors here (no route to host)
323 if we fail to send to all nameservers, send back an error
324 packet straight away (helps modem users when offline) */
325
326 if (!flags && forward)
327 {
de37951c
SK
328 struct server *firstsentto = start;
329 int forwarded = 0;
28866e95
SK
330
331 if (udpaddr && option_bool(OPT_ADD_MAC))
332 plen = add_mac(header, plen, ((char *) header) + PACKETSZ, udpaddr);
333
9e4abcb5
SK
334 while (1)
335 {
9e4abcb5
SK
336 /* only send to servers dealing with our domain.
337 domain may be NULL, in which case server->domain
338 must be NULL also. */
339
de37951c 340 if (type == (start->flags & SERV_TYPE) &&
fd9fa481
SK
341 (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
342 !(start->flags & SERV_LITERAL_ADDRESS))
9e4abcb5 343 {
1a6bca81
SK
344 int fd;
345
346 /* find server socket to use, may need to get random one. */
347 if (start->sfd)
348 fd = start->sfd->fd;
349 else
350 {
351#ifdef HAVE_IPV6
352 if (start->addr.sa.sa_family == AF_INET6)
353 {
354 if (!forward->rfd6 &&
355 !(forward->rfd6 = allocate_rfd(AF_INET6)))
356 break;
3927da46 357 daemon->rfd_save = forward->rfd6;
1a6bca81
SK
358 fd = forward->rfd6->fd;
359 }
360 else
361#endif
362 {
363 if (!forward->rfd4 &&
364 !(forward->rfd4 = allocate_rfd(AF_INET)))
365 break;
3927da46 366 daemon->rfd_save = forward->rfd4;
1a6bca81
SK
367 fd = forward->rfd4->fd;
368 }
7de060b0
SK
369
370#ifdef HAVE_CONNTRACK
371 /* Copy connection mark of incoming query to outgoing connection. */
372 if (option_bool(OPT_CONNTRACK))
373 {
374 unsigned int mark;
375 if (get_incoming_mark(udpaddr, dst_addr, 0, &mark))
376 setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
377 }
378#endif
1a6bca81
SK
379 }
380
381 if (sendto(fd, (char *)header, plen, 0,
feba5c1d 382 &start->addr.sa,
fd9fa481
SK
383 sa_len(&start->addr)) == -1)
384 {
385 if (retry_send())
386 continue;
387 }
388 else
9e4abcb5 389 {
cdeda28f
SK
390 /* Keep info in case we want to re-send this packet */
391 daemon->srv_save = start;
392 daemon->packet_len = plen;
393
de37951c 394 if (!gotname)
3be34541 395 strcpy(daemon->namebuff, "query");
de37951c 396 if (start->addr.sa.sa_family == AF_INET)
3be34541 397 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 398 (struct all_addr *)&start->addr.in.sin_addr, NULL);
de37951c
SK
399#ifdef HAVE_IPV6
400 else
3be34541 401 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 402 (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
de37951c 403#endif
824af85b 404 start->queries++;
de37951c
SK
405 forwarded = 1;
406 forward->sentto = start;
0a852541 407 if (!forward->forwardall)
de37951c 408 break;
0a852541 409 forward->forwardall++;
9e4abcb5
SK
410 }
411 }
412
de37951c 413 if (!(start = start->next))
3be34541 414 start = daemon->servers;
9e4abcb5 415
de37951c 416 if (start == firstsentto)
9e4abcb5
SK
417 break;
418 }
419
de37951c 420 if (forwarded)
824af85b 421 return 1;
de37951c 422
9e4abcb5
SK
423 /* could not send on, prepare to return */
424 header->id = htons(forward->orig_id);
1a6bca81 425 free_frec(forward); /* cancel */
9e4abcb5
SK
426 }
427
428 /* could not send on, return empty answer or address if known for whole domain */
b8187c80
SK
429 if (udpfd != -1)
430 {
cdeda28f 431 plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
54dd393f 432 send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
b8187c80
SK
433 }
434
824af85b 435 return 0;
9e4abcb5
SK
436}
437
572b41eb 438static size_t process_reply(struct dns_header *header, time_t now,
28866e95 439 struct server *server, size_t n, int check_rebind, int checking_disabled)
feba5c1d 440{
36717eee 441 unsigned char *pheader, *sizep;
832af0ba 442 int munged = 0, is_sign;
cdeda28f
SK
443 size_t plen;
444
feba5c1d 445 /* If upstream is advertising a larger UDP packet size
9009d746
SK
446 than we allow, trim it so that we don't get overlarge
447 requests for the client. We can't do this for signed packets. */
feba5c1d 448
832af0ba 449 if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
feba5c1d
SK
450 {
451 unsigned short udpsz;
36717eee 452 unsigned char *psave = sizep;
feba5c1d 453
36717eee 454 GETSHORT(udpsz, sizep);
3be34541
SK
455 if (udpsz > daemon->edns_pktsz)
456 PUTSHORT(daemon->edns_pktsz, psave);
feba5c1d
SK
457 }
458
28866e95
SK
459 /* RFC 4035 sect 4.6 para 3 */
460 if (!is_sign && !option_bool(OPT_DNSSEC))
572b41eb 461 header->hb4 &= ~HB4_AD;
28866e95 462
572b41eb 463 if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
0a852541
SK
464 return n;
465
feba5c1d 466 /* Complain loudly if the upstream server is non-recursive. */
572b41eb 467 if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR && ntohs(header->ancount) == 0 &&
0a852541 468 server && !(server->flags & SERV_WARNED_RECURSIVE))
feba5c1d 469 {
3d8df260 470 prettyprint_addr(&server->addr, daemon->namebuff);
f2621c7f 471 my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
28866e95 472 if (!option_bool(OPT_LOG))
0a852541
SK
473 server->flags |= SERV_WARNED_RECURSIVE;
474 }
475
572b41eb 476 if (daemon->bogus_addr && RCODE(header) != NXDOMAIN &&
fd9fa481 477 check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
feba5c1d 478 {
fd9fa481 479 munged = 1;
572b41eb
SK
480 SET_RCODE(header, NXDOMAIN);
481 header->hb3 &= ~HB3_AA;
36717eee 482 }
fd9fa481 483 else
36717eee 484 {
572b41eb 485 if (RCODE(header) == NXDOMAIN &&
fd9fa481 486 extract_request(header, n, daemon->namebuff, NULL) &&
5aabfc78 487 check_for_local_domain(daemon->namebuff, now))
36717eee
SK
488 {
489 /* if we forwarded a query for a locally known name (because it was for
490 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
491 since we know that the domain exists, even if upstream doesn't */
fd9fa481 492 munged = 1;
572b41eb
SK
493 header->hb3 |= HB3_AA;
494 SET_RCODE(header, NOERROR);
feba5c1d 495 }
832af0ba 496
28866e95 497 if (extract_addresses(header, n, daemon->namebuff, now, is_sign, check_rebind, checking_disabled))
824af85b 498 {
8ef5ada2 499 my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
824af85b
SK
500 munged = 1;
501 }
feba5c1d 502 }
fd9fa481
SK
503
504 /* do this after extract_addresses. Ensure NODATA reply and remove
505 nameserver info. */
506
507 if (munged)
508 {
509 header->ancount = htons(0);
510 header->nscount = htons(0);
511 header->arcount = htons(0);
512 }
513
36717eee
SK
514 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
515 sections of the packet. Find the new length here and put back pseudoheader
516 if it was removed. */
517 return resize_packet(header, n, pheader, plen);
feba5c1d
SK
518}
519
3be34541 520/* sets new last_server */
1a6bca81 521void reply_query(int fd, int family, time_t now)
9e4abcb5
SK
522{
523 /* packet from peer server, extract data for cache, and send to
524 original requester */
572b41eb 525 struct dns_header *header;
de37951c 526 union mysockaddr serveraddr;
832af0ba 527 struct frec *forward;
de37951c 528 socklen_t addrlen = sizeof(serveraddr);
1a6bca81 529 ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
cdeda28f 530 size_t nn;
1a6bca81
SK
531 struct server *server;
532
cdeda28f
SK
533 /* packet buffer overwritten */
534 daemon->srv_save = NULL;
832af0ba 535
de37951c 536 /* Determine the address of the server replying so that we can mark that as good */
1a6bca81 537 serveraddr.sa.sa_family = family;
de37951c
SK
538#ifdef HAVE_IPV6
539 if (serveraddr.sa.sa_family == AF_INET6)
5e9e0efb 540 serveraddr.in6.sin6_flowinfo = 0;
de37951c 541#endif
9e4abcb5 542
1a6bca81
SK
543 /* spoof check: answer must come from known server, */
544 for (server = daemon->servers; server; server = server->next)
545 if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
546 sockaddr_isequal(&server->addr, &serveraddr))
547 break;
548
572b41eb 549 header = (struct dns_header *)daemon->packet;
fd9fa481 550
1a6bca81 551 if (!server ||
572b41eb 552 n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR) ||
1a6bca81
SK
553 !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
554 return;
555
556 server = forward->sentto;
557
572b41eb 558 if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
28866e95 559 !option_bool(OPT_ORDER) &&
1a6bca81
SK
560 forward->forwardall == 0)
561 /* for broken servers, attempt to send to another one. */
9e4abcb5 562 {
1a6bca81
SK
563 unsigned char *pheader;
564 size_t plen;
565 int is_sign;
832af0ba 566
1a6bca81
SK
567 /* recreate query from reply */
568 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
569 if (!is_sign)
832af0ba 570 {
1a6bca81
SK
571 header->ancount = htons(0);
572 header->nscount = htons(0);
573 header->arcount = htons(0);
574 if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
832af0ba 575 {
572b41eb 576 header->hb3 &= ~(HB3_QR | HB3_TC);
1a6bca81
SK
577 forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
578 return;
832af0ba 579 }
832af0ba 580 }
1a6bca81
SK
581 }
582
583 if ((forward->sentto->flags & SERV_TYPE) == 0)
584 {
572b41eb 585 if (RCODE(header) == SERVFAIL || RCODE(header) == REFUSED)
1a6bca81
SK
586 server = NULL;
587 else
b8187c80 588 {
1a6bca81
SK
589 struct server *last_server;
590
591 /* find good server by address if possible, otherwise assume the last one we sent to */
592 for (last_server = daemon->servers; last_server; last_server = last_server->next)
593 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
594 sockaddr_isequal(&last_server->addr, &serveraddr))
595 {
596 server = last_server;
597 break;
598 }
599 }
28866e95 600 if (!option_bool(OPT_ALL_SERVERS))
1a6bca81
SK
601 daemon->last_server = server;
602 }
603
604 /* If the answer is an error, keep the forward record in place in case
605 we get a good reply from another server. Kill it when we've
606 had replies from all to avoid filling the forwarding table when
607 everything is broken */
608 if (forward->forwardall == 0 || --forward->forwardall == 1 ||
572b41eb 609 (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
1a6bca81 610 {
28866e95 611 int check_rebind = !(forward->flags & FREC_NOREBIND);
8ef5ada2 612
28866e95 613 if (!option_bool(OPT_NO_REBIND))
8ef5ada2
SK
614 check_rebind = 0;
615
28866e95 616 if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, forward->flags & FREC_CHECKING_DISABLED)))
1a6bca81
SK
617 {
618 header->id = htons(forward->orig_id);
572b41eb 619 header->hb4 |= HB4_RA; /* recursion if available */
54dd393f 620 send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
50303b19 621 &forward->source, &forward->dest, forward->iface);
b8187c80 622 }
1a6bca81 623 free_frec(forward); /* cancel */
9e4abcb5 624 }
9e4abcb5 625}
44a2a316 626
1a6bca81 627
5aabfc78 628void receive_query(struct listener *listen, time_t now)
44a2a316 629{
572b41eb 630 struct dns_header *header = (struct dns_header *)daemon->packet;
44a2a316 631 union mysockaddr source_addr;
c1bb8504 632 unsigned short type;
44a2a316 633 struct all_addr dst_addr;
f6b7dc47 634 struct in_addr netmask, dst_addr_4;
cdeda28f
SK
635 size_t m;
636 ssize_t n;
637 int if_index = 0;
4f7b304f 638 int auth_dns = 0;
44a2a316
SK
639 struct iovec iov[1];
640 struct msghdr msg;
641 struct cmsghdr *cmptr;
44a2a316
SK
642 union {
643 struct cmsghdr align; /* this ensures alignment */
644#ifdef HAVE_IPV6
645 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
646#endif
5e9e0efb 647#if defined(HAVE_LINUX_NETWORK)
44a2a316 648 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
824af85b
SK
649#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
650 char control[CMSG_SPACE(sizeof(struct in_addr)) +
651 CMSG_SPACE(sizeof(unsigned int))];
44a2a316
SK
652#elif defined(IP_RECVDSTADDR)
653 char control[CMSG_SPACE(sizeof(struct in_addr)) +
654 CMSG_SPACE(sizeof(struct sockaddr_dl))];
655#endif
656 } control_u;
657
cdeda28f
SK
658 /* packet buffer overwritten */
659 daemon->srv_save = NULL;
660
4f7b304f
SK
661 dst_addr_4.s_addr = 0;
662 netmask.s_addr = 0;
663
664 if (listen->iface && option_bool(OPT_NOWILD))
3d8df260 665 {
4f7b304f
SK
666 auth_dns = listen->iface->dns_auth;
667
668 if (listen->family == AF_INET)
669 {
670 dst_addr_4 = listen->iface->addr.in.sin_addr;
671 netmask = listen->iface->netmask;
672 }
3d8df260 673 }
4f7b304f 674
3be34541
SK
675 iov[0].iov_base = daemon->packet;
676 iov[0].iov_len = daemon->edns_pktsz;
44a2a316
SK
677
678 msg.msg_control = control_u.control;
679 msg.msg_controllen = sizeof(control_u);
680 msg.msg_flags = 0;
681 msg.msg_name = &source_addr;
682 msg.msg_namelen = sizeof(source_addr);
683 msg.msg_iov = iov;
684 msg.msg_iovlen = 1;
685
de37951c 686 if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
3be34541 687 return;
44a2a316 688
572b41eb 689 if (n < (int)sizeof(struct dns_header) ||
5e9e0efb 690 (msg.msg_flags & MSG_TRUNC) ||
572b41eb 691 (header->hb3 & HB3_QR))
26128d27
SK
692 return;
693
44a2a316
SK
694 source_addr.sa.sa_family = listen->family;
695#ifdef HAVE_IPV6
696 if (listen->family == AF_INET6)
5e9e0efb 697 source_addr.in6.sin6_flowinfo = 0;
44a2a316 698#endif
28866e95
SK
699
700 if (!option_bool(OPT_NOWILD))
26128d27
SK
701 {
702 struct ifreq ifr;
703
704 if (msg.msg_controllen < sizeof(struct cmsghdr))
705 return;
44a2a316 706
5e9e0efb 707#if defined(HAVE_LINUX_NETWORK)
26128d27
SK
708 if (listen->family == AF_INET)
709 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
c72daea8 710 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
26128d27 711 {
8ef5ada2
SK
712 union {
713 unsigned char *c;
714 struct in_pktinfo *p;
715 } p;
716 p.c = CMSG_DATA(cmptr);
717 dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
718 if_index = p.p->ipi_ifindex;
26128d27
SK
719 }
720#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
721 if (listen->family == AF_INET)
44a2a316 722 {
26128d27 723 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
8ef5ada2
SK
724 {
725 union {
726 unsigned char *c;
727 unsigned int *i;
728 struct in_addr *a;
729#ifndef HAVE_SOLARIS_NETWORK
730 struct sockaddr_dl *s;
731#endif
732 } p;
733 p.c = CMSG_DATA(cmptr);
734 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
735 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
736 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
824af85b 737#ifdef HAVE_SOLARIS_NETWORK
8ef5ada2 738 if_index = *(p.i);
824af85b 739#else
8ef5ada2 740 if_index = p.s->sdl_index;
824af85b 741#endif
8ef5ada2 742 }
44a2a316 743 }
44a2a316 744#endif
26128d27 745
44a2a316 746#ifdef HAVE_IPV6
26128d27
SK
747 if (listen->family == AF_INET6)
748 {
749 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
c72daea8 750 if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
26128d27 751 {
8ef5ada2
SK
752 union {
753 unsigned char *c;
754 struct in6_pktinfo *p;
755 } p;
756 p.c = CMSG_DATA(cmptr);
757
758 dst_addr.addr.addr6 = p.p->ipi6_addr;
759 if_index = p.p->ipi6_ifindex;
26128d27
SK
760 }
761 }
44a2a316 762#endif
26128d27
SK
763
764 /* enforce available interface configuration */
765
e25db1f2 766 if (!indextoname(listen->fd, if_index, ifr.ifr_name))
5e9e0efb 767 return;
832af0ba 768
e25db1f2
SK
769 if (!iface_check(listen->family, &dst_addr, ifr.ifr_name, &auth_dns))
770 {
771 if (!option_bool(OPT_CLEVERBIND))
772 enumerate_interfaces();
773 if (!loopback_exception(listen->fd, listen->family, &dst_addr, ifr.ifr_name))
774 return;
775 }
776
552af8b9
SK
777 if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
778 {
779 struct irec *iface;
780
781 /* get the netmask of the interface whch has the address we were sent to.
782 This is no neccessarily the interface we arrived on. */
783
784 for (iface = daemon->interfaces; iface; iface = iface->next)
785 if (iface->addr.sa.sa_family == AF_INET &&
786 iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
787 break;
788
789 /* interface may be new */
e25db1f2 790 if (!iface && !option_bool(OPT_CLEVERBIND))
552af8b9
SK
791 enumerate_interfaces();
792
793 for (iface = daemon->interfaces; iface; iface = iface->next)
794 if (iface->addr.sa.sa_family == AF_INET &&
795 iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
796 break;
797
798 /* If we failed, abandon localisation */
799 if (iface)
800 netmask = iface->netmask;
801 else
802 dst_addr_4.s_addr = 0;
803 }
44a2a316
SK
804 }
805
cdeda28f 806 if (extract_request(header, (size_t)n, daemon->namebuff, &type))
44a2a316 807 {
1a6bca81
SK
808 char types[20];
809
4f7b304f 810 querystr(auth_dns ? "auth" : "query", types, type);
1a6bca81 811
44a2a316 812 if (listen->family == AF_INET)
3be34541 813 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 814 (struct all_addr *)&source_addr.in.sin_addr, types);
44a2a316
SK
815#ifdef HAVE_IPV6
816 else
3be34541 817 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 818 (struct all_addr *)&source_addr.in6.sin6_addr, types);
44a2a316
SK
819#endif
820 }
821
4820dce9 822#ifdef HAVE_AUTH
4f7b304f 823 if (auth_dns)
824af85b 824 {
49678767 825 m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr);
4f7b304f
SK
826 if (m >= 1)
827 send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
828 (char *)header, m, &source_addr, &dst_addr, if_index);
824af85b 829 }
44a2a316 830 else
4820dce9 831#endif
4f7b304f
SK
832 {
833 m = answer_request(header, ((char *) header) + PACKETSZ, (size_t)n,
834 dst_addr_4, netmask, now);
835
836 if (m >= 1)
837 {
838 send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
839 (char *)header, m, &source_addr, &dst_addr, if_index);
840 daemon->local_answer++;
841 }
842 else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
843 header, (size_t)n, now, NULL))
844 daemon->queries_forwarded++;
845 else
846 daemon->local_answer++;
847 }
44a2a316
SK
848}
849
feba5c1d
SK
850/* The daemon forks before calling this: it should deal with one connection,
851 blocking as neccessary, and then return. Note, need to be a bit careful
852 about resources for debug mode, when the fork is suppressed: that's
853 done by the caller. */
5aabfc78 854unsigned char *tcp_request(int confd, time_t now,
4f7b304f 855 union mysockaddr *local_addr, struct in_addr netmask, int auth_dns)
feba5c1d 856{
28866e95
SK
857 size_t size = 0;
858 int norebind = 0;
859 int checking_disabled;
cdeda28f 860 size_t m;
ee86ce68
SK
861 unsigned short qtype;
862 unsigned int gotname;
feba5c1d
SK
863 unsigned char c1, c2;
864 /* Max TCP packet + slop */
5aabfc78 865 unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
572b41eb 866 struct dns_header *header;
3be34541 867 struct server *last_server;
7de060b0
SK
868 struct in_addr dst_addr_4;
869 union mysockaddr peer_addr;
870 socklen_t peer_len = sizeof(union mysockaddr);
3be34541 871
7de060b0
SK
872 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) == -1)
873 return packet;
874
feba5c1d
SK
875 while (1)
876 {
877 if (!packet ||
878 !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
879 !(size = c1 << 8 | c2) ||
880 !read_write(confd, packet, size, 1))
881 return packet;
882
572b41eb 883 if (size < (int)sizeof(struct dns_header))
feba5c1d
SK
884 continue;
885
572b41eb 886 header = (struct dns_header *)packet;
28866e95
SK
887
888 /* save state of "cd" flag in query */
572b41eb 889 checking_disabled = header->hb4 & HB4_CD;
28866e95
SK
890
891 /* RFC 4035: sect 4.6 para 2 */
572b41eb 892 header->hb4 &= ~HB4_AD;
feba5c1d 893
3be34541 894 if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
feba5c1d 895 {
7de060b0 896 char types[20];
feba5c1d 897
4f7b304f 898 querystr(auth_dns ? "auth" : "query", types, qtype);
7de060b0
SK
899
900 if (peer_addr.sa.sa_family == AF_INET)
901 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
902 (struct all_addr *)&peer_addr.in.sin_addr, types);
feba5c1d 903#ifdef HAVE_IPV6
7de060b0
SK
904 else
905 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
906 (struct all_addr *)&peer_addr.in6.sin6_addr, types);
feba5c1d 907#endif
feba5c1d
SK
908 }
909
7de060b0
SK
910 if (local_addr->sa.sa_family == AF_INET)
911 dst_addr_4 = local_addr->in.sin_addr;
912 else
913 dst_addr_4.s_addr = 0;
914
4820dce9 915#ifdef HAVE_AUTH
4f7b304f 916 if (auth_dns)
49678767 917 m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr);
4f7b304f 918 else
4820dce9 919#endif
feba5c1d 920 {
4f7b304f
SK
921 /* m > 0 if answered from cache */
922 m = answer_request(header, ((char *) header) + 65536, (size_t)size,
923 dst_addr_4, netmask, now);
feba5c1d 924
4f7b304f
SK
925 /* Do this by steam now we're not in the select() loop */
926 check_log_writer(NULL);
927
928 if (m == 0)
feba5c1d 929 {
4f7b304f
SK
930 unsigned int flags = 0;
931 struct all_addr *addrp = NULL;
932 int type = 0;
933 char *domain = NULL;
feba5c1d 934
4f7b304f
SK
935 if (option_bool(OPT_ADD_MAC))
936 size = add_mac(header, size, ((char *) header) + 65536, &peer_addr);
937
938 if (gotname)
939 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
940
941 if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server)
942 last_server = daemon->servers;
943 else
944 last_server = daemon->last_server;
945
946 if (!flags && last_server)
947 {
948 struct server *firstsendto = NULL;
949 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
950
951 /* Loop round available servers until we succeed in connecting to one.
952 Note that this code subtley ensures that consecutive queries on this connection
953 which can go to the same server, do so. */
954 while (1)
feba5c1d 955 {
4f7b304f
SK
956 if (!firstsendto)
957 firstsendto = last_server;
958 else
959 {
960 if (!(last_server = last_server->next))
961 last_server = daemon->servers;
962
963 if (last_server == firstsendto)
964 break;
965 }
966
967 /* server for wrong domain */
968 if (type != (last_server->flags & SERV_TYPE) ||
969 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
7de060b0
SK
970 continue;
971
4f7b304f 972 if (last_server->tcpfd == -1)
7de060b0 973 {
4f7b304f
SK
974 if ((last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) == -1)
975 continue;
976
977 if ((!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
978 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
979 {
980 close(last_server->tcpfd);
981 last_server->tcpfd = -1;
982 continue;
983 }
984
7de060b0 985#ifdef HAVE_CONNTRACK
4f7b304f
SK
986 /* Copy connection mark of incoming query to outgoing connection. */
987 if (option_bool(OPT_CONNTRACK))
988 {
989 unsigned int mark;
990 struct all_addr local;
7de060b0 991#ifdef HAVE_IPV6
4f7b304f
SK
992 if (local_addr->sa.sa_family == AF_INET6)
993 local.addr.addr6 = local_addr->in6.sin6_addr;
994 else
7de060b0 995#endif
4f7b304f
SK
996 local.addr.addr4 = local_addr->in.sin_addr;
997
998 if (get_incoming_mark(&peer_addr, &local, 1, &mark))
999 setsockopt(last_server->tcpfd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
1000 }
7de060b0 1001#endif
4f7b304f
SK
1002 }
1003
1004 c1 = size >> 8;
1005 c2 = size;
1006
1007 if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
1008 !read_write(last_server->tcpfd, &c2, 1, 0) ||
1009 !read_write(last_server->tcpfd, packet, size, 0) ||
1010 !read_write(last_server->tcpfd, &c1, 1, 1) ||
1011 !read_write(last_server->tcpfd, &c2, 1, 1))
1012 {
1013 close(last_server->tcpfd);
1014 last_server->tcpfd = -1;
1015 continue;
1016 }
1017
1018 m = (c1 << 8) | c2;
1019 if (!read_write(last_server->tcpfd, packet, m, 1))
1020 return packet;
1021
1022 if (!gotname)
1023 strcpy(daemon->namebuff, "query");
1024 if (last_server->addr.sa.sa_family == AF_INET)
1025 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1026 (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
feba5c1d 1027#ifdef HAVE_IPV6
4f7b304f
SK
1028 else
1029 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1030 (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
feba5c1d 1031#endif
4f7b304f
SK
1032
1033 /* There's no point in updating the cache, since this process will exit and
1034 lose the information after a few queries. We make this call for the alias and
1035 bogus-nxdomain side-effects. */
1036 /* If the crc of the question section doesn't match the crc we sent, then
1037 someone might be attempting to insert bogus values into the cache by
1038 sending replies containing questions and bogus answers. */
1039 if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
1040 m = process_reply(header, now, last_server, (unsigned int)m,
1041 option_bool(OPT_NO_REBIND) && !norebind, checking_disabled);
1042
1043 break;
1044 }
feba5c1d 1045 }
4f7b304f
SK
1046
1047 /* In case of local answer or no connections made. */
1048 if (m == 0)
1049 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
feba5c1d 1050 }
feba5c1d 1051 }
4f7b304f 1052
5aabfc78 1053 check_log_writer(NULL);
feba5c1d
SK
1054
1055 c1 = m>>8;
1056 c2 = m;
49678767
SK
1057 if (m == 0 ||
1058 !read_write(confd, &c1, 1, 0) ||
feba5c1d
SK
1059 !read_write(confd, &c2, 1, 0) ||
1060 !read_write(confd, packet, m, 0))
1061 return packet;
1062 }
1063}
1064
1697269c 1065static struct frec *allocate_frec(time_t now)
9e4abcb5 1066{
1697269c
SK
1067 struct frec *f;
1068
5aabfc78 1069 if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
9e4abcb5 1070 {
1a6bca81 1071 f->next = daemon->frec_list;
1697269c 1072 f->time = now;
832af0ba 1073 f->sentto = NULL;
1a6bca81 1074 f->rfd4 = NULL;
28866e95 1075 f->flags = 0;
1a6bca81
SK
1076#ifdef HAVE_IPV6
1077 f->rfd6 = NULL;
1078#endif
1079 daemon->frec_list = f;
1697269c 1080 }
9e4abcb5 1081
1697269c
SK
1082 return f;
1083}
9e4abcb5 1084
1a6bca81
SK
1085static struct randfd *allocate_rfd(int family)
1086{
1087 static int finger = 0;
1088 int i;
1089
1090 /* limit the number of sockets we have open to avoid starvation of
1091 (eg) TFTP. Once we have a reasonable number, randomness should be OK */
1092
1093 for (i = 0; i < RANDOM_SOCKS; i++)
9009d746 1094 if (daemon->randomsocks[i].refcount == 0)
1a6bca81 1095 {
9009d746
SK
1096 if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
1097 break;
1098
1a6bca81
SK
1099 daemon->randomsocks[i].refcount = 1;
1100 daemon->randomsocks[i].family = family;
1101 return &daemon->randomsocks[i];
1102 }
1103
9009d746 1104 /* No free ones or cannot get new socket, grab an existing one */
1a6bca81
SK
1105 for (i = 0; i < RANDOM_SOCKS; i++)
1106 {
1107 int j = (i+finger) % RANDOM_SOCKS;
9009d746
SK
1108 if (daemon->randomsocks[j].refcount != 0 &&
1109 daemon->randomsocks[j].family == family &&
1110 daemon->randomsocks[j].refcount != 0xffff)
1a6bca81
SK
1111 {
1112 finger = j;
1113 daemon->randomsocks[j].refcount++;
1114 return &daemon->randomsocks[j];
1115 }
1116 }
1117
1118 return NULL; /* doom */
1119}
1120
1121static void free_frec(struct frec *f)
1122{
1123 if (f->rfd4 && --(f->rfd4->refcount) == 0)
1124 close(f->rfd4->fd);
1125
1126 f->rfd4 = NULL;
1127 f->sentto = NULL;
28866e95 1128 f->flags = 0;
1a6bca81
SK
1129
1130#ifdef HAVE_IPV6
1131 if (f->rfd6 && --(f->rfd6->refcount) == 0)
1132 close(f->rfd6->fd);
1133
1134 f->rfd6 = NULL;
1135#endif
1136}
1137
1697269c
SK
1138/* if wait==NULL return a free or older than TIMEOUT record.
1139 else return *wait zero if one available, or *wait is delay to
1a6bca81
SK
1140 when the oldest in-use record will expire. Impose an absolute
1141 limit of 4*TIMEOUT before we wipe things (for random sockets) */
5aabfc78 1142struct frec *get_new_frec(time_t now, int *wait)
1697269c 1143{
1a6bca81 1144 struct frec *f, *oldest, *target;
1697269c
SK
1145 int count;
1146
1147 if (wait)
1148 *wait = 0;
1149
1a6bca81 1150 for (f = daemon->frec_list, oldest = NULL, target = NULL, count = 0; f; f = f->next, count++)
832af0ba 1151 if (!f->sentto)
1a6bca81
SK
1152 target = f;
1153 else
1697269c 1154 {
1a6bca81
SK
1155 if (difftime(now, f->time) >= 4*TIMEOUT)
1156 {
1157 free_frec(f);
1158 target = f;
1159 }
1160
1161 if (!oldest || difftime(f->time, oldest->time) <= 0)
1162 oldest = f;
1697269c 1163 }
1a6bca81
SK
1164
1165 if (target)
1166 {
1167 target->time = now;
1168 return target;
1169 }
9e4abcb5
SK
1170
1171 /* can't find empty one, use oldest if there is one
1172 and it's older than timeout */
1697269c 1173 if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
9e4abcb5 1174 {
1697269c
SK
1175 /* keep stuff for twice timeout if we can by allocating a new
1176 record instead */
1177 if (difftime(now, oldest->time) < 2*TIMEOUT &&
1178 count <= daemon->ftabsize &&
1179 (f = allocate_frec(now)))
1180 return f;
1181
1182 if (!wait)
1183 {
1a6bca81 1184 free_frec(oldest);
1697269c
SK
1185 oldest->time = now;
1186 }
9e4abcb5
SK
1187 return oldest;
1188 }
1189
1697269c 1190 /* none available, calculate time 'till oldest record expires */
208b65c5 1191 if (count > daemon->ftabsize)
1697269c
SK
1192 {
1193 if (oldest && wait)
1194 *wait = oldest->time + (time_t)TIMEOUT - now;
9e4abcb5
SK
1195 return NULL;
1196 }
1697269c
SK
1197
1198 if (!(f = allocate_frec(now)) && wait)
1199 /* wait one second on malloc failure */
1200 *wait = 1;
9e4abcb5 1201
9e4abcb5
SK
1202 return f; /* OK if malloc fails and this is NULL */
1203}
1204
832af0ba
SK
1205/* crc is all-ones if not known. */
1206static struct frec *lookup_frec(unsigned short id, unsigned int crc)
9e4abcb5
SK
1207{
1208 struct frec *f;
1209
1a6bca81 1210 for(f = daemon->frec_list; f; f = f->next)
832af0ba
SK
1211 if (f->sentto && f->new_id == id &&
1212 (f->crc == crc || crc == 0xffffffff))
9e4abcb5
SK
1213 return f;
1214
1215 return NULL;
1216}
1217
1218static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481
SK
1219 union mysockaddr *addr,
1220 unsigned int crc)
9e4abcb5 1221{
feba5c1d
SK
1222 struct frec *f;
1223
1a6bca81 1224 for(f = daemon->frec_list; f; f = f->next)
832af0ba 1225 if (f->sentto &&
9e4abcb5 1226 f->orig_id == id &&
fd9fa481 1227 f->crc == crc &&
9e4abcb5
SK
1228 sockaddr_isequal(&f->source, addr))
1229 return f;
1230
1231 return NULL;
1232}
1233
849a8357 1234/* A server record is going away, remove references to it */
5aabfc78 1235void server_gone(struct server *server)
849a8357
SK
1236{
1237 struct frec *f;
1238
1a6bca81 1239 for (f = daemon->frec_list; f; f = f->next)
832af0ba 1240 if (f->sentto && f->sentto == server)
1a6bca81 1241 free_frec(f);
849a8357
SK
1242
1243 if (daemon->last_server == server)
1244 daemon->last_server = NULL;
1245
1246 if (daemon->srv_save == server)
1247 daemon->srv_save = NULL;
1248}
9e4abcb5 1249
316e2730
SK
1250/* return unique random ids. */
1251static unsigned short get_id(unsigned int crc)
9e4abcb5
SK
1252{
1253 unsigned short ret = 0;
832af0ba 1254
316e2730 1255 do
832af0ba
SK
1256 ret = rand16();
1257 while (lookup_frec(ret, crc));
1258
9e4abcb5
SK
1259 return ret;
1260}
1261
1262
1263
1264
1265