]> git.ipfire.org Git - people/ms/dnsmasq.git/blame - src/forward.c
import of dnsmasq-2.57.tar.gz
[people/ms/dnsmasq.git] / src / forward.c
CommitLineData
28866e95 1/* dnsmasq is Copyright (c) 2000-2011 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 */
cdeda28f 29static void send_from(int fd, int nowild, char *packet, size_t len,
dfa666f2
SK
30 union mysockaddr *to, struct all_addr *source,
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
SK
72 msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
73 cmptr->cmsg_level = SOL_IP;
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;
26128d27
SK
91 cmptr->cmsg_level = IPV6_LEVEL;
92 }
3d8df260
SK
93#else
94 iface = 0; /* eliminate warning */
44a2a316 95#endif
26128d27 96 }
feba5c1d 97
fd9fa481
SK
98 retry:
99 if (sendmsg(fd, &msg, 0) == -1)
feba5c1d 100 {
fd9fa481
SK
101 /* certain Linux kernels seem to object to setting the source address in the IPv6 stack
102 by returning EINVAL from sendmsg. In that case, try again without setting the
103 source address, since it will nearly alway be correct anyway. IPv6 stinks. */
104 if (errno == EINVAL && msg.msg_controllen)
105 {
106 msg.msg_controllen = 0;
107 goto retry;
108 }
109 if (retry_send())
110 goto retry;
feba5c1d 111 }
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
28866e95
SK
210 if (flags == 0 && !(qtype & F_NSRR) &&
211 option_bool(OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
824af85b 212 /* don't forward simple names, make exception for NS queries and empty name. */
36717eee 213 flags = F_NXDOMAIN;
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;
3d8df260 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 }
369 }
370
371 if (sendto(fd, (char *)header, plen, 0,
feba5c1d 372 &start->addr.sa,
fd9fa481
SK
373 sa_len(&start->addr)) == -1)
374 {
375 if (retry_send())
376 continue;
377 }
378 else
9e4abcb5 379 {
cdeda28f
SK
380 /* Keep info in case we want to re-send this packet */
381 daemon->srv_save = start;
382 daemon->packet_len = plen;
383
de37951c 384 if (!gotname)
3be34541 385 strcpy(daemon->namebuff, "query");
de37951c 386 if (start->addr.sa.sa_family == AF_INET)
3be34541 387 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 388 (struct all_addr *)&start->addr.in.sin_addr, NULL);
de37951c
SK
389#ifdef HAVE_IPV6
390 else
3be34541 391 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 392 (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
de37951c 393#endif
824af85b 394 start->queries++;
de37951c
SK
395 forwarded = 1;
396 forward->sentto = start;
0a852541 397 if (!forward->forwardall)
de37951c 398 break;
0a852541 399 forward->forwardall++;
9e4abcb5
SK
400 }
401 }
402
de37951c 403 if (!(start = start->next))
3be34541 404 start = daemon->servers;
9e4abcb5 405
de37951c 406 if (start == firstsentto)
9e4abcb5
SK
407 break;
408 }
409
de37951c 410 if (forwarded)
824af85b 411 return 1;
de37951c 412
9e4abcb5
SK
413 /* could not send on, prepare to return */
414 header->id = htons(forward->orig_id);
1a6bca81 415 free_frec(forward); /* cancel */
9e4abcb5
SK
416 }
417
418 /* could not send on, return empty answer or address if known for whole domain */
b8187c80
SK
419 if (udpfd != -1)
420 {
cdeda28f 421 plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
28866e95 422 send_from(udpfd, option_bool(OPT_NOWILD), (char *)header, plen, udpaddr, dst_addr, dst_iface);
b8187c80
SK
423 }
424
824af85b 425 return 0;
9e4abcb5
SK
426}
427
572b41eb 428static size_t process_reply(struct dns_header *header, time_t now,
28866e95 429 struct server *server, size_t n, int check_rebind, int checking_disabled)
feba5c1d 430{
36717eee 431 unsigned char *pheader, *sizep;
832af0ba 432 int munged = 0, is_sign;
cdeda28f
SK
433 size_t plen;
434
feba5c1d 435 /* If upstream is advertising a larger UDP packet size
9009d746
SK
436 than we allow, trim it so that we don't get overlarge
437 requests for the client. We can't do this for signed packets. */
feba5c1d 438
832af0ba 439 if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
feba5c1d
SK
440 {
441 unsigned short udpsz;
36717eee 442 unsigned char *psave = sizep;
feba5c1d 443
36717eee 444 GETSHORT(udpsz, sizep);
3be34541
SK
445 if (udpsz > daemon->edns_pktsz)
446 PUTSHORT(daemon->edns_pktsz, psave);
feba5c1d
SK
447 }
448
28866e95
SK
449 /* RFC 4035 sect 4.6 para 3 */
450 if (!is_sign && !option_bool(OPT_DNSSEC))
572b41eb 451 header->hb4 &= ~HB4_AD;
28866e95 452
572b41eb 453 if (OPCODE(header) != QUERY || (RCODE(header) != NOERROR && RCODE(header) != NXDOMAIN))
0a852541
SK
454 return n;
455
feba5c1d 456 /* Complain loudly if the upstream server is non-recursive. */
572b41eb 457 if (!(header->hb4 & HB4_RA) && RCODE(header) == NOERROR && ntohs(header->ancount) == 0 &&
0a852541 458 server && !(server->flags & SERV_WARNED_RECURSIVE))
feba5c1d 459 {
3d8df260 460 prettyprint_addr(&server->addr, daemon->namebuff);
f2621c7f 461 my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
28866e95 462 if (!option_bool(OPT_LOG))
0a852541
SK
463 server->flags |= SERV_WARNED_RECURSIVE;
464 }
465
572b41eb 466 if (daemon->bogus_addr && RCODE(header) != NXDOMAIN &&
fd9fa481 467 check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now))
feba5c1d 468 {
fd9fa481 469 munged = 1;
572b41eb
SK
470 SET_RCODE(header, NXDOMAIN);
471 header->hb3 &= ~HB3_AA;
36717eee 472 }
fd9fa481 473 else
36717eee 474 {
572b41eb 475 if (RCODE(header) == NXDOMAIN &&
fd9fa481 476 extract_request(header, n, daemon->namebuff, NULL) &&
5aabfc78 477 check_for_local_domain(daemon->namebuff, now))
36717eee
SK
478 {
479 /* if we forwarded a query for a locally known name (because it was for
480 an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
481 since we know that the domain exists, even if upstream doesn't */
fd9fa481 482 munged = 1;
572b41eb
SK
483 header->hb3 |= HB3_AA;
484 SET_RCODE(header, NOERROR);
feba5c1d 485 }
832af0ba 486
28866e95 487 if (extract_addresses(header, n, daemon->namebuff, now, is_sign, check_rebind, checking_disabled))
824af85b 488 {
8ef5ada2 489 my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected: %s"), daemon->namebuff);
824af85b
SK
490 munged = 1;
491 }
feba5c1d 492 }
fd9fa481
SK
493
494 /* do this after extract_addresses. Ensure NODATA reply and remove
495 nameserver info. */
496
497 if (munged)
498 {
499 header->ancount = htons(0);
500 header->nscount = htons(0);
501 header->arcount = htons(0);
502 }
503
36717eee
SK
504 /* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
505 sections of the packet. Find the new length here and put back pseudoheader
506 if it was removed. */
507 return resize_packet(header, n, pheader, plen);
feba5c1d
SK
508}
509
3be34541 510/* sets new last_server */
1a6bca81 511void reply_query(int fd, int family, time_t now)
9e4abcb5
SK
512{
513 /* packet from peer server, extract data for cache, and send to
514 original requester */
572b41eb 515 struct dns_header *header;
de37951c 516 union mysockaddr serveraddr;
832af0ba 517 struct frec *forward;
de37951c 518 socklen_t addrlen = sizeof(serveraddr);
1a6bca81 519 ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
cdeda28f 520 size_t nn;
1a6bca81
SK
521 struct server *server;
522
cdeda28f
SK
523 /* packet buffer overwritten */
524 daemon->srv_save = NULL;
832af0ba 525
de37951c 526 /* Determine the address of the server replying so that we can mark that as good */
1a6bca81 527 serveraddr.sa.sa_family = family;
de37951c
SK
528#ifdef HAVE_IPV6
529 if (serveraddr.sa.sa_family == AF_INET6)
5e9e0efb 530 serveraddr.in6.sin6_flowinfo = 0;
de37951c 531#endif
9e4abcb5 532
1a6bca81
SK
533 /* spoof check: answer must come from known server, */
534 for (server = daemon->servers; server; server = server->next)
535 if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
536 sockaddr_isequal(&server->addr, &serveraddr))
537 break;
538
572b41eb 539 header = (struct dns_header *)daemon->packet;
fd9fa481 540
1a6bca81 541 if (!server ||
572b41eb 542 n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR) ||
1a6bca81
SK
543 !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
544 return;
545
546 server = forward->sentto;
547
572b41eb 548 if ((RCODE(header) == SERVFAIL || RCODE(header) == REFUSED) &&
28866e95 549 !option_bool(OPT_ORDER) &&
1a6bca81
SK
550 forward->forwardall == 0)
551 /* for broken servers, attempt to send to another one. */
9e4abcb5 552 {
1a6bca81
SK
553 unsigned char *pheader;
554 size_t plen;
555 int is_sign;
832af0ba 556
1a6bca81
SK
557 /* recreate query from reply */
558 pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
559 if (!is_sign)
832af0ba 560 {
1a6bca81
SK
561 header->ancount = htons(0);
562 header->nscount = htons(0);
563 header->arcount = htons(0);
564 if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
832af0ba 565 {
572b41eb 566 header->hb3 &= ~(HB3_QR | HB3_TC);
1a6bca81
SK
567 forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
568 return;
832af0ba 569 }
832af0ba 570 }
1a6bca81
SK
571 }
572
573 if ((forward->sentto->flags & SERV_TYPE) == 0)
574 {
572b41eb 575 if (RCODE(header) == SERVFAIL || RCODE(header) == REFUSED)
1a6bca81
SK
576 server = NULL;
577 else
b8187c80 578 {
1a6bca81
SK
579 struct server *last_server;
580
581 /* find good server by address if possible, otherwise assume the last one we sent to */
582 for (last_server = daemon->servers; last_server; last_server = last_server->next)
583 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
584 sockaddr_isequal(&last_server->addr, &serveraddr))
585 {
586 server = last_server;
587 break;
588 }
589 }
28866e95 590 if (!option_bool(OPT_ALL_SERVERS))
1a6bca81
SK
591 daemon->last_server = server;
592 }
593
594 /* If the answer is an error, keep the forward record in place in case
595 we get a good reply from another server. Kill it when we've
596 had replies from all to avoid filling the forwarding table when
597 everything is broken */
598 if (forward->forwardall == 0 || --forward->forwardall == 1 ||
572b41eb 599 (RCODE(header) != REFUSED && RCODE(header) != SERVFAIL))
1a6bca81 600 {
28866e95 601 int check_rebind = !(forward->flags & FREC_NOREBIND);
8ef5ada2 602
28866e95 603 if (!option_bool(OPT_NO_REBIND))
8ef5ada2
SK
604 check_rebind = 0;
605
28866e95 606 if ((nn = process_reply(header, now, server, (size_t)n, check_rebind, forward->flags & FREC_CHECKING_DISABLED)))
1a6bca81
SK
607 {
608 header->id = htons(forward->orig_id);
572b41eb 609 header->hb4 |= HB4_RA; /* recursion if available */
28866e95 610 send_from(forward->fd, option_bool(OPT_NOWILD), daemon->packet, nn,
1a6bca81 611 &forward->source, &forward->dest, forward->iface);
b8187c80 612 }
1a6bca81 613 free_frec(forward); /* cancel */
9e4abcb5 614 }
9e4abcb5 615}
44a2a316 616
1a6bca81 617
5aabfc78 618void receive_query(struct listener *listen, time_t now)
44a2a316 619{
572b41eb 620 struct dns_header *header = (struct dns_header *)daemon->packet;
44a2a316 621 union mysockaddr source_addr;
c1bb8504 622 unsigned short type;
44a2a316 623 struct all_addr dst_addr;
f6b7dc47 624 struct in_addr netmask, dst_addr_4;
cdeda28f
SK
625 size_t m;
626 ssize_t n;
627 int if_index = 0;
44a2a316
SK
628 struct iovec iov[1];
629 struct msghdr msg;
630 struct cmsghdr *cmptr;
44a2a316
SK
631 union {
632 struct cmsghdr align; /* this ensures alignment */
633#ifdef HAVE_IPV6
634 char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
635#endif
5e9e0efb 636#if defined(HAVE_LINUX_NETWORK)
44a2a316 637 char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
824af85b
SK
638#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
639 char control[CMSG_SPACE(sizeof(struct in_addr)) +
640 CMSG_SPACE(sizeof(unsigned int))];
44a2a316
SK
641#elif defined(IP_RECVDSTADDR)
642 char control[CMSG_SPACE(sizeof(struct in_addr)) +
643 CMSG_SPACE(sizeof(struct sockaddr_dl))];
644#endif
645 } control_u;
646
cdeda28f
SK
647 /* packet buffer overwritten */
648 daemon->srv_save = NULL;
649
28866e95 650 if (listen->family == AF_INET && option_bool(OPT_NOWILD))
f6b7dc47
SK
651 {
652 dst_addr_4 = listen->iface->addr.in.sin_addr;
653 netmask = listen->iface->netmask;
654 }
655 else
3d8df260
SK
656 {
657 dst_addr_4.s_addr = 0;
658 netmask.s_addr = 0;
659 }
f6b7dc47 660
3be34541
SK
661 iov[0].iov_base = daemon->packet;
662 iov[0].iov_len = daemon->edns_pktsz;
44a2a316
SK
663
664 msg.msg_control = control_u.control;
665 msg.msg_controllen = sizeof(control_u);
666 msg.msg_flags = 0;
667 msg.msg_name = &source_addr;
668 msg.msg_namelen = sizeof(source_addr);
669 msg.msg_iov = iov;
670 msg.msg_iovlen = 1;
671
de37951c 672 if ((n = recvmsg(listen->fd, &msg, 0)) == -1)
3be34541 673 return;
44a2a316 674
572b41eb 675 if (n < (int)sizeof(struct dns_header) ||
5e9e0efb 676 (msg.msg_flags & MSG_TRUNC) ||
572b41eb 677 (header->hb3 & HB3_QR))
26128d27
SK
678 return;
679
44a2a316
SK
680 source_addr.sa.sa_family = listen->family;
681#ifdef HAVE_IPV6
682 if (listen->family == AF_INET6)
5e9e0efb 683 source_addr.in6.sin6_flowinfo = 0;
44a2a316 684#endif
28866e95
SK
685
686 if (!option_bool(OPT_NOWILD))
26128d27
SK
687 {
688 struct ifreq ifr;
689
690 if (msg.msg_controllen < sizeof(struct cmsghdr))
691 return;
44a2a316 692
5e9e0efb 693#if defined(HAVE_LINUX_NETWORK)
26128d27
SK
694 if (listen->family == AF_INET)
695 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
696 if (cmptr->cmsg_level == SOL_IP && cmptr->cmsg_type == IP_PKTINFO)
697 {
8ef5ada2
SK
698 union {
699 unsigned char *c;
700 struct in_pktinfo *p;
701 } p;
702 p.c = CMSG_DATA(cmptr);
703 dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst;
704 if_index = p.p->ipi_ifindex;
26128d27
SK
705 }
706#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
707 if (listen->family == AF_INET)
44a2a316 708 {
26128d27 709 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
8ef5ada2
SK
710 {
711 union {
712 unsigned char *c;
713 unsigned int *i;
714 struct in_addr *a;
715#ifndef HAVE_SOLARIS_NETWORK
716 struct sockaddr_dl *s;
717#endif
718 } p;
719 p.c = CMSG_DATA(cmptr);
720 if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
721 dst_addr_4 = dst_addr.addr.addr4 = *(p.a);
722 else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
824af85b 723#ifdef HAVE_SOLARIS_NETWORK
8ef5ada2 724 if_index = *(p.i);
824af85b 725#else
8ef5ada2 726 if_index = p.s->sdl_index;
824af85b 727#endif
8ef5ada2 728 }
44a2a316 729 }
44a2a316 730#endif
26128d27 731
44a2a316 732#ifdef HAVE_IPV6
26128d27
SK
733 if (listen->family == AF_INET6)
734 {
735 for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
316e2730 736 if (cmptr->cmsg_level == IPV6_LEVEL && cmptr->cmsg_type == daemon->v6pktinfo)
26128d27 737 {
8ef5ada2
SK
738 union {
739 unsigned char *c;
740 struct in6_pktinfo *p;
741 } p;
742 p.c = CMSG_DATA(cmptr);
743
744 dst_addr.addr.addr6 = p.p->ipi6_addr;
745 if_index = p.p->ipi6_ifindex;
26128d27
SK
746 }
747 }
44a2a316 748#endif
26128d27
SK
749
750 /* enforce available interface configuration */
751
7622fc06
SK
752 if (!indextoname(listen->fd, if_index, ifr.ifr_name) ||
753 !iface_check(listen->family, &dst_addr, ifr.ifr_name, &if_index))
5e9e0efb 754 return;
832af0ba
SK
755
756 if (listen->family == AF_INET &&
28866e95 757 option_bool(OPT_LOCALISE) &&
832af0ba
SK
758 ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
759 return;
760
761 netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
44a2a316
SK
762 }
763
cdeda28f 764 if (extract_request(header, (size_t)n, daemon->namebuff, &type))
44a2a316 765 {
1a6bca81
SK
766 char types[20];
767
768 querystr(types, type);
769
44a2a316 770 if (listen->family == AF_INET)
3be34541 771 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 772 (struct all_addr *)&source_addr.in.sin_addr, types);
44a2a316
SK
773#ifdef HAVE_IPV6
774 else
3be34541 775 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 776 (struct all_addr *)&source_addr.in6.sin6_addr, types);
44a2a316
SK
777#endif
778 }
779
5aabfc78 780 m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n,
f6b7dc47 781 dst_addr_4, netmask, now);
44a2a316 782 if (m >= 1)
824af85b 783 {
28866e95 784 send_from(listen->fd, option_bool(OPT_NOWILD), (char *)header,
824af85b
SK
785 m, &source_addr, &dst_addr, if_index);
786 daemon->local_answer++;
787 }
788 else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
789 header, (size_t)n, now, NULL))
790 daemon->queries_forwarded++;
44a2a316 791 else
824af85b 792 daemon->local_answer++;
44a2a316
SK
793}
794
feba5c1d
SK
795/* The daemon forks before calling this: it should deal with one connection,
796 blocking as neccessary, and then return. Note, need to be a bit careful
797 about resources for debug mode, when the fork is suppressed: that's
798 done by the caller. */
5aabfc78 799unsigned char *tcp_request(int confd, time_t now,
3d8df260 800 struct in_addr local_addr, struct in_addr netmask)
feba5c1d 801{
28866e95
SK
802 size_t size = 0;
803 int norebind = 0;
804 int checking_disabled;
cdeda28f 805 size_t m;
c1bb8504 806 unsigned short qtype, gotname;
feba5c1d
SK
807 unsigned char c1, c2;
808 /* Max TCP packet + slop */
5aabfc78 809 unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
572b41eb 810 struct dns_header *header;
3be34541
SK
811 struct server *last_server;
812
feba5c1d
SK
813 while (1)
814 {
815 if (!packet ||
816 !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) ||
817 !(size = c1 << 8 | c2) ||
818 !read_write(confd, packet, size, 1))
819 return packet;
820
572b41eb 821 if (size < (int)sizeof(struct dns_header))
feba5c1d
SK
822 continue;
823
572b41eb 824 header = (struct dns_header *)packet;
28866e95
SK
825
826 /* save state of "cd" flag in query */
572b41eb 827 checking_disabled = header->hb4 & HB4_CD;
28866e95
SK
828
829 /* RFC 4035: sect 4.6 para 2 */
572b41eb 830 header->hb4 &= ~HB4_AD;
feba5c1d 831
3be34541 832 if ((gotname = extract_request(header, (unsigned int)size, daemon->namebuff, &qtype)))
feba5c1d
SK
833 {
834 union mysockaddr peer_addr;
835 socklen_t peer_len = sizeof(union mysockaddr);
836
837 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
838 {
1a6bca81
SK
839 char types[20];
840
841 querystr(types, qtype);
842
feba5c1d 843 if (peer_addr.sa.sa_family == AF_INET)
3be34541 844 log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 845 (struct all_addr *)&peer_addr.in.sin_addr, types);
feba5c1d
SK
846#ifdef HAVE_IPV6
847 else
3be34541 848 log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 849 (struct all_addr *)&peer_addr.in6.sin6_addr, types);
feba5c1d
SK
850#endif
851 }
852 }
853
854 /* m > 0 if answered from cache */
5aabfc78 855 m = answer_request(header, ((char *) header) + 65536, (unsigned int)size,
f6b7dc47 856 local_addr, netmask, now);
5aabfc78
SK
857
858 /* Do this by steam now we're not in the select() loop */
859 check_log_writer(NULL);
feba5c1d
SK
860
861 if (m == 0)
862 {
28866e95 863 unsigned int flags = 0;
feba5c1d
SK
864 struct all_addr *addrp = NULL;
865 int type = 0;
866 char *domain = NULL;
28866e95
SK
867
868 if (option_bool(OPT_ADD_MAC))
869 {
870 union mysockaddr peer_addr;
871 socklen_t peer_len = sizeof(union mysockaddr);
872
873 if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
874 size = add_mac(header, size, ((char *) header) + 65536, &peer_addr);
875 }
876
feba5c1d 877 if (gotname)
8ef5ada2 878 flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
feba5c1d 879
28866e95 880 if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server)
3be34541
SK
881 last_server = daemon->servers;
882 else
883 last_server = daemon->last_server;
feba5c1d
SK
884
885 if (!flags && last_server)
886 {
887 struct server *firstsendto = NULL;
0a852541
SK
888 unsigned int crc = questions_crc(header, (unsigned int)size, daemon->namebuff);
889
feba5c1d
SK
890 /* Loop round available servers until we succeed in connecting to one.
891 Note that this code subtley ensures that consecutive queries on this connection
892 which can go to the same server, do so. */
893 while (1)
8ef5ada2 894 {
feba5c1d
SK
895 if (!firstsendto)
896 firstsendto = last_server;
897 else
898 {
899 if (!(last_server = last_server->next))
3be34541 900 last_server = daemon->servers;
feba5c1d
SK
901
902 if (last_server == firstsendto)
903 break;
904 }
905
906 /* server for wrong domain */
907 if (type != (last_server->flags & SERV_TYPE) ||
908 (type == SERV_HAS_DOMAIN && !hostname_isequal(domain, last_server->domain)))
909 continue;
910
911 if ((last_server->tcpfd == -1) &&
912 (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
824af85b
SK
913 (!local_bind(last_server->tcpfd, &last_server->source_addr, last_server->interface, 1) ||
914 connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
feba5c1d
SK
915 {
916 close(last_server->tcpfd);
917 last_server->tcpfd = -1;
918 }
919
920 if (last_server->tcpfd == -1)
921 continue;
824af85b 922
feba5c1d
SK
923 c1 = size >> 8;
924 c2 = size;
925
926 if (!read_write(last_server->tcpfd, &c1, 1, 0) ||
927 !read_write(last_server->tcpfd, &c2, 1, 0) ||
928 !read_write(last_server->tcpfd, packet, size, 0) ||
929 !read_write(last_server->tcpfd, &c1, 1, 1) ||
930 !read_write(last_server->tcpfd, &c2, 1, 1))
931 {
932 close(last_server->tcpfd);
933 last_server->tcpfd = -1;
934 continue;
935 }
824af85b 936
feba5c1d
SK
937 m = (c1 << 8) | c2;
938 if (!read_write(last_server->tcpfd, packet, m, 1))
939 return packet;
940
941 if (!gotname)
3be34541 942 strcpy(daemon->namebuff, "query");
feba5c1d 943 if (last_server->addr.sa.sa_family == AF_INET)
3be34541 944 log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff,
1a6bca81 945 (struct all_addr *)&last_server->addr.in.sin_addr, NULL);
feba5c1d
SK
946#ifdef HAVE_IPV6
947 else
3be34541 948 log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff,
1a6bca81 949 (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
feba5c1d
SK
950#endif
951
952 /* There's no point in updating the cache, since this process will exit and
832af0ba 953 lose the information after a few queries. We make this call for the alias and
feba5c1d 954 bogus-nxdomain side-effects. */
832af0ba
SK
955 /* If the crc of the question section doesn't match the crc we sent, then
956 someone might be attempting to insert bogus values into the cache by
957 sending replies containing questions and bogus answers. */
958 if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
28866e95
SK
959 m = process_reply(header, now, last_server, (unsigned int)m,
960 option_bool(OPT_NO_REBIND) && !norebind, checking_disabled);
feba5c1d
SK
961
962 break;
963 }
964 }
965
966 /* In case of local answer or no connections made. */
967 if (m == 0)
3be34541 968 m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
feba5c1d 969 }
5aabfc78
SK
970
971 check_log_writer(NULL);
feba5c1d
SK
972
973 c1 = m>>8;
974 c2 = m;
975 if (!read_write(confd, &c1, 1, 0) ||
976 !read_write(confd, &c2, 1, 0) ||
977 !read_write(confd, packet, m, 0))
978 return packet;
979 }
980}
981
1697269c 982static struct frec *allocate_frec(time_t now)
9e4abcb5 983{
1697269c
SK
984 struct frec *f;
985
5aabfc78 986 if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
9e4abcb5 987 {
1a6bca81 988 f->next = daemon->frec_list;
1697269c 989 f->time = now;
832af0ba 990 f->sentto = NULL;
1a6bca81 991 f->rfd4 = NULL;
28866e95 992 f->flags = 0;
1a6bca81
SK
993#ifdef HAVE_IPV6
994 f->rfd6 = NULL;
995#endif
996 daemon->frec_list = f;
1697269c 997 }
9e4abcb5 998
1697269c
SK
999 return f;
1000}
9e4abcb5 1001
1a6bca81
SK
1002static struct randfd *allocate_rfd(int family)
1003{
1004 static int finger = 0;
1005 int i;
1006
1007 /* limit the number of sockets we have open to avoid starvation of
1008 (eg) TFTP. Once we have a reasonable number, randomness should be OK */
1009
1010 for (i = 0; i < RANDOM_SOCKS; i++)
9009d746 1011 if (daemon->randomsocks[i].refcount == 0)
1a6bca81 1012 {
9009d746
SK
1013 if ((daemon->randomsocks[i].fd = random_sock(family)) == -1)
1014 break;
1015
1a6bca81
SK
1016 daemon->randomsocks[i].refcount = 1;
1017 daemon->randomsocks[i].family = family;
1018 return &daemon->randomsocks[i];
1019 }
1020
9009d746 1021 /* No free ones or cannot get new socket, grab an existing one */
1a6bca81
SK
1022 for (i = 0; i < RANDOM_SOCKS; i++)
1023 {
1024 int j = (i+finger) % RANDOM_SOCKS;
9009d746
SK
1025 if (daemon->randomsocks[j].refcount != 0 &&
1026 daemon->randomsocks[j].family == family &&
1027 daemon->randomsocks[j].refcount != 0xffff)
1a6bca81
SK
1028 {
1029 finger = j;
1030 daemon->randomsocks[j].refcount++;
1031 return &daemon->randomsocks[j];
1032 }
1033 }
1034
1035 return NULL; /* doom */
1036}
1037
1038static void free_frec(struct frec *f)
1039{
1040 if (f->rfd4 && --(f->rfd4->refcount) == 0)
1041 close(f->rfd4->fd);
1042
1043 f->rfd4 = NULL;
1044 f->sentto = NULL;
28866e95 1045 f->flags = 0;
1a6bca81
SK
1046
1047#ifdef HAVE_IPV6
1048 if (f->rfd6 && --(f->rfd6->refcount) == 0)
1049 close(f->rfd6->fd);
1050
1051 f->rfd6 = NULL;
1052#endif
1053}
1054
1697269c
SK
1055/* if wait==NULL return a free or older than TIMEOUT record.
1056 else return *wait zero if one available, or *wait is delay to
1a6bca81
SK
1057 when the oldest in-use record will expire. Impose an absolute
1058 limit of 4*TIMEOUT before we wipe things (for random sockets) */
5aabfc78 1059struct frec *get_new_frec(time_t now, int *wait)
1697269c 1060{
1a6bca81 1061 struct frec *f, *oldest, *target;
1697269c
SK
1062 int count;
1063
1064 if (wait)
1065 *wait = 0;
1066
1a6bca81 1067 for (f = daemon->frec_list, oldest = NULL, target = NULL, count = 0; f; f = f->next, count++)
832af0ba 1068 if (!f->sentto)
1a6bca81
SK
1069 target = f;
1070 else
1697269c 1071 {
1a6bca81
SK
1072 if (difftime(now, f->time) >= 4*TIMEOUT)
1073 {
1074 free_frec(f);
1075 target = f;
1076 }
1077
1078 if (!oldest || difftime(f->time, oldest->time) <= 0)
1079 oldest = f;
1697269c 1080 }
1a6bca81
SK
1081
1082 if (target)
1083 {
1084 target->time = now;
1085 return target;
1086 }
9e4abcb5
SK
1087
1088 /* can't find empty one, use oldest if there is one
1089 and it's older than timeout */
1697269c 1090 if (oldest && ((int)difftime(now, oldest->time)) >= TIMEOUT)
9e4abcb5 1091 {
1697269c
SK
1092 /* keep stuff for twice timeout if we can by allocating a new
1093 record instead */
1094 if (difftime(now, oldest->time) < 2*TIMEOUT &&
1095 count <= daemon->ftabsize &&
1096 (f = allocate_frec(now)))
1097 return f;
1098
1099 if (!wait)
1100 {
1a6bca81 1101 free_frec(oldest);
1697269c
SK
1102 oldest->time = now;
1103 }
9e4abcb5
SK
1104 return oldest;
1105 }
1106
1697269c 1107 /* none available, calculate time 'till oldest record expires */
208b65c5 1108 if (count > daemon->ftabsize)
1697269c
SK
1109 {
1110 if (oldest && wait)
1111 *wait = oldest->time + (time_t)TIMEOUT - now;
9e4abcb5
SK
1112 return NULL;
1113 }
1697269c
SK
1114
1115 if (!(f = allocate_frec(now)) && wait)
1116 /* wait one second on malloc failure */
1117 *wait = 1;
9e4abcb5 1118
9e4abcb5
SK
1119 return f; /* OK if malloc fails and this is NULL */
1120}
1121
832af0ba
SK
1122/* crc is all-ones if not known. */
1123static struct frec *lookup_frec(unsigned short id, unsigned int crc)
9e4abcb5
SK
1124{
1125 struct frec *f;
1126
1a6bca81 1127 for(f = daemon->frec_list; f; f = f->next)
832af0ba
SK
1128 if (f->sentto && f->new_id == id &&
1129 (f->crc == crc || crc == 0xffffffff))
9e4abcb5
SK
1130 return f;
1131
1132 return NULL;
1133}
1134
1135static struct frec *lookup_frec_by_sender(unsigned short id,
fd9fa481
SK
1136 union mysockaddr *addr,
1137 unsigned int crc)
9e4abcb5 1138{
feba5c1d
SK
1139 struct frec *f;
1140
1a6bca81 1141 for(f = daemon->frec_list; f; f = f->next)
832af0ba 1142 if (f->sentto &&
9e4abcb5 1143 f->orig_id == id &&
fd9fa481 1144 f->crc == crc &&
9e4abcb5
SK
1145 sockaddr_isequal(&f->source, addr))
1146 return f;
1147
1148 return NULL;
1149}
1150
849a8357 1151/* A server record is going away, remove references to it */
5aabfc78 1152void server_gone(struct server *server)
849a8357
SK
1153{
1154 struct frec *f;
1155
1a6bca81 1156 for (f = daemon->frec_list; f; f = f->next)
832af0ba 1157 if (f->sentto && f->sentto == server)
1a6bca81 1158 free_frec(f);
849a8357
SK
1159
1160 if (daemon->last_server == server)
1161 daemon->last_server = NULL;
1162
1163 if (daemon->srv_save == server)
1164 daemon->srv_save = NULL;
1165}
9e4abcb5 1166
316e2730
SK
1167/* return unique random ids. */
1168static unsigned short get_id(unsigned int crc)
9e4abcb5
SK
1169{
1170 unsigned short ret = 0;
832af0ba 1171
316e2730 1172 do
832af0ba
SK
1173 ret = rand16();
1174 while (lookup_frec(ret, crc));
1175
9e4abcb5
SK
1176 return ret;
1177}
1178
1179
1180
1181
1182