~ubuntu-branches/debian/lenny/dnsmasq/lenny

« back to all changes in this revision

Viewing changes to src/forward.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Kelley
  • Date: 2008-07-20 19:27:11 UTC
  • mfrom: (0.3.1 upstream) (9.1.4 hardy)
  • Revision ID: james.westby@ubuntu.com-20080720192711-b0lg0kl8egyg0v1b
Tags: 2.45-1
New upstream - fixes regression when min-port not set.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* dnsmasq is Copyright (c) 2000 - 2005 Simon Kelley
 
1
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
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
 
 
 
5
   the Free Software Foundation; version 2 dated June, 1991, or
 
6
   (at your option) version 3 dated 29 June, 2007.
 
7
 
7
8
   This program is distributed in the hope that it will be useful,
8
9
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
11
   GNU General Public License for more details.
 
12
     
 
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/>.
11
15
*/
12
16
 
13
17
#include "dnsmasq.h"
14
18
 
15
 
static struct frec *frec_list = NULL;
16
 
 
17
 
static struct frec *lookup_frec(unsigned short id);
 
19
static struct frec *lookup_frec(unsigned short id, unsigned int crc);
18
20
static struct frec *lookup_frec_by_sender(unsigned short id,
19
21
                                          union mysockaddr *addr,
20
22
                                          unsigned int crc);
21
 
static unsigned short get_id(void);
22
 
 
23
 
 
24
 
/* Send a UDP packet with it's source address set as "source" 
 
23
static unsigned short get_id(int force, unsigned short force_id, unsigned int crc);
 
24
static void free_frec(struct frec *f);
 
25
static struct randfd *allocate_rfd(int family);
 
26
 
 
27
/* Send a UDP packet with its source address set as "source" 
25
28
   unless nowild is true, when we just send it with the kernel default */
26
29
static void send_from(int fd, int nowild, char *packet, size_t len, 
27
30
                      union mysockaddr *to, struct all_addr *source,
107
110
    }
108
111
}
109
112
          
110
 
static unsigned short search_servers(struct daemon *daemon, time_t now, struct all_addr **addrpp, 
 
113
static unsigned short search_servers(time_t now, struct all_addr **addrpp, 
111
114
                                     unsigned short qtype, char *qdomain, int *type, char **domain)
112
115
                              
113
116
{
140
143
                  *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
141
144
#endif 
142
145
              }
143
 
            else if (!flags)
 
146
            else if (!flags || (flags & F_NXDOMAIN))
144
147
              flags = F_NOERR;
145
148
          } 
146
149
      }
161
164
              flags = F_NXDOMAIN;
162
165
            else if (serv->flags & SERV_LITERAL_ADDRESS)
163
166
              {
164
 
                if ((sflag | F_QUERY ) & qtype)
 
167
                if (sflag & qtype)
165
168
                  {
166
 
                    flags = qtype;
 
169
                    flags = sflag;
167
170
                    if (serv->addr.sa.sa_family == AF_INET) 
168
171
                      *addrpp = (struct all_addr *)&serv->addr.in.sin_addr;
169
172
#ifdef HAVE_IPV6
171
174
                      *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
172
175
#endif
173
176
                  }
174
 
                else if (!flags)
 
177
                else if (!flags || (flags & F_NXDOMAIN))
175
178
                  flags = F_NOERR;
176
179
              }
177
180
          } 
178
181
      }
179
182
 
180
 
  if (flags & ~(F_NOERR | F_NXDOMAIN)) /* flags set here means a literal found */
181
 
    {
182
 
      if (flags & F_QUERY)
183
 
        log_query(F_CONFIG | F_FORWARD | F_NEG, qdomain, NULL, 0, NULL, 0);
184
 
      else
185
 
        log_query(F_CONFIG | F_FORWARD | flags, qdomain, *addrpp, 0, NULL, 0);
186
 
    }
187
 
  else if (qtype && (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
 
183
  if (flags == 0 && !(qtype & F_BIGNAME) && 
 
184
      (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.') && namelen != 0)
 
185
    /* don't forward simple names, make exception for NS queries and empty name. */
188
186
    flags = F_NXDOMAIN;
189
187
    
190
 
  if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now, daemon))
 
188
  if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now))
191
189
    flags = F_NOERR;
192
190
 
193
 
  if (flags == F_NXDOMAIN || flags == F_NOERR)
194
 
    log_query(F_CONFIG | F_FORWARD | F_NEG | qtype | (flags & F_NXDOMAIN), qdomain, NULL, 0, NULL, 0);
 
191
  if (flags)
 
192
    {
 
193
      int logflags = 0;
 
194
      
 
195
      if (flags == F_NXDOMAIN || flags == F_NOERR)
 
196
        logflags = F_NEG | qtype;
 
197
  
 
198
      log_query(logflags | flags | F_CONFIG | F_FORWARD, qdomain, *addrpp, NULL);
 
199
    }
195
200
 
196
201
  return  flags;
197
202
}
198
203
 
199
 
/* returns new last_server */   
200
 
static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *udpaddr,
201
 
                          struct all_addr *dst_addr, unsigned int dst_iface,
202
 
                          HEADER *header, size_t plen, time_t now, struct frec *forward)
 
204
static int forward_query(int udpfd, union mysockaddr *udpaddr,
 
205
                         struct all_addr *dst_addr, unsigned int dst_iface,
 
206
                         HEADER *header, size_t plen, time_t now, struct frec *forward)
203
207
{
204
208
  char *domain = NULL;
205
209
  int type = 0;
216
220
    {
217
221
      /* retry on existing query, send to all available servers  */
218
222
      domain = forward->sentto->domain;
 
223
      forward->sentto->failed_queries++;
219
224
      if (!(daemon->options & OPT_ORDER))
220
225
        {
221
226
          forward->forwardall = 1;
229
234
  else 
230
235
    {
231
236
      if (gotname)
232
 
        flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain);
 
237
        flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
233
238
      
234
 
      if (!flags && !(forward = get_new_frec(daemon, now, NULL)))
 
239
      if (!flags && !(forward = get_new_frec(now, NULL)))
235
240
        /* table full - server failure. */
236
241
        flags = F_NEG;
237
242
      
238
243
      if (forward)
239
244
        {
 
245
          /* force unchanging id for signed packets */
 
246
          int is_sign;
 
247
          find_pseudoheader(header, plen, NULL, NULL, &is_sign);
 
248
          
240
249
          forward->source = *udpaddr;
241
250
          forward->dest = *dst_addr;
242
251
          forward->iface = dst_iface;
243
 
          forward->new_id = get_id();
 
252
          forward->orig_id = ntohs(header->id);
 
253
          forward->new_id = get_id(is_sign, forward->orig_id, crc);
244
254
          forward->fd = udpfd;
245
 
          forward->orig_id = ntohs(header->id);
246
255
          forward->crc = crc;
247
256
          forward->forwardall = 0;
248
257
          header->id = htons(forward->new_id);
280
289
              (type != SERV_HAS_DOMAIN || hostname_isequal(domain, start->domain)) &&
281
290
              !(start->flags & SERV_LITERAL_ADDRESS))
282
291
            {
283
 
              if (sendto(start->sfd->fd, (char *)header, plen, 0,
 
292
              int fd;
 
293
 
 
294
              /* find server socket to use, may need to get random one. */
 
295
              if (start->sfd)
 
296
                fd = start->sfd->fd;
 
297
              else 
 
298
                {
 
299
#ifdef HAVE_IPV6
 
300
                  if (start->addr.sa.sa_family == AF_INET6)
 
301
                    {
 
302
                      if (!forward->rfd6 &&
 
303
                          !(forward->rfd6 = allocate_rfd(AF_INET6)))
 
304
                        break;
 
305
                      daemon->rfd_save = forward->rfd6;
 
306
                      fd = forward->rfd6->fd;
 
307
                    }
 
308
                  else
 
309
#endif
 
310
                    {
 
311
                      if (!forward->rfd4 &&
 
312
                          !(forward->rfd4 = allocate_rfd(AF_INET)))
 
313
                        break;
 
314
                      daemon->rfd_save = forward->rfd4;
 
315
                      fd = forward->rfd4->fd;
 
316
                    }
 
317
                }
 
318
              
 
319
              if (sendto(fd, (char *)header, plen, 0,
284
320
                         &start->addr.sa,
285
321
                         sa_len(&start->addr)) == -1)
286
322
                {
297
333
                    strcpy(daemon->namebuff, "query");
298
334
                  if (start->addr.sa.sa_family == AF_INET)
299
335
                    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
300
 
                              (struct all_addr *)&start->addr.in.sin_addr, 0,
301
 
                              NULL, 0); 
 
336
                              (struct all_addr *)&start->addr.in.sin_addr, NULL); 
302
337
#ifdef HAVE_IPV6
303
338
                  else
304
339
                    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
305
 
                              (struct all_addr *)&start->addr.in6.sin6_addr, 0,
306
 
                              NULL, 0);
 
340
                              (struct all_addr *)&start->addr.in6.sin6_addr, NULL);
307
341
#endif 
 
342
                  start->queries++;
308
343
                  forwarded = 1;
309
344
                  forward->sentto = start;
310
345
                  if (!forward->forwardall) 
321
356
        }
322
357
      
323
358
      if (forwarded)
324
 
          return;
 
359
        return 1;
325
360
      
326
361
      /* could not send on, prepare to return */ 
327
362
      header->id = htons(forward->orig_id);
328
 
      forward->new_id = 0; /* cancel */
 
363
      free_frec(forward); /* cancel */
329
364
    }     
330
365
  
331
366
  /* could not send on, return empty answer or address if known for whole domain */
335
370
      send_from(udpfd, daemon->options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface);
336
371
    }
337
372
 
338
 
  return;
 
373
  return 0;
339
374
}
340
375
 
341
 
static size_t process_reply(struct daemon *daemon, HEADER *header, time_t now, 
342
 
                            unsigned int query_crc, struct server *server, size_t n)
 
376
static size_t process_reply(HEADER *header, time_t now, 
 
377
                            struct server *server, size_t n)
343
378
{
344
379
  unsigned char *pheader, *sizep;
345
 
  int munged = 0;
 
380
  int munged = 0, is_sign;
346
381
  size_t plen; 
347
382
 
348
383
  /* If upstream is advertising a larger UDP packet size
349
384
         than we allow, trim it so that we don't get overlarge
350
 
         requests for the client. */
 
385
         requests for the client. We can't do this for signed packets. */
351
386
 
352
 
  if ((pheader = find_pseudoheader(header, n, &plen, &sizep)))
 
387
  if ((pheader = find_pseudoheader(header, n, &plen, &sizep, &is_sign)) && !is_sign)
353
388
    {
354
389
      unsigned short udpsz;
355
390
      unsigned char *psave = sizep;
367
402
      server && !(server->flags & SERV_WARNED_RECURSIVE))
368
403
    {
369
404
      prettyprint_addr(&server->addr, daemon->namebuff);
370
 
      syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
 
405
      my_syslog(LOG_WARNING, _("nameserver %s refused to do a recursive query"), daemon->namebuff);
371
406
      if (!(daemon->options & OPT_LOG))
372
407
        server->flags |= SERV_WARNED_RECURSIVE;
373
408
    }  
383
418
    {
384
419
      if (header->rcode == NXDOMAIN && 
385
420
          extract_request(header, n, daemon->namebuff, NULL) &&
386
 
          check_for_local_domain(daemon->namebuff, now, daemon))
 
421
          check_for_local_domain(daemon->namebuff, now))
387
422
        {
388
423
          /* if we forwarded a query for a locally known name (because it was for 
389
424
             an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
392
427
          header->aa = 1;
393
428
          header->rcode = NOERROR;
394
429
        }
395
 
  
396
 
      /* If the crc of the question section doesn't match the crc we sent, then
397
 
         someone might be attempting to insert bogus values into the cache by 
398
 
         sending replies containing questions and bogus answers. */
399
 
      if (query_crc == questions_crc(header, n, daemon->namebuff))
400
 
        extract_addresses(header, n, daemon->namebuff, now, daemon);
 
430
      
 
431
      if (extract_addresses(header, n, daemon->namebuff, now))
 
432
        {
 
433
          my_syslog(LOG_WARNING, _("possible DNS-rebind attack detected"));
 
434
          munged = 1;
 
435
        }
401
436
    }
402
437
  
403
438
  /* do this after extract_addresses. Ensure NODATA reply and remove
417
452
}
418
453
 
419
454
/* sets new last_server */
420
 
void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now)
 
455
void reply_query(int fd, int family, time_t now)
421
456
{
422
457
  /* packet from peer server, extract data for cache, and send to
423
458
     original requester */
 
459
  HEADER *header;
 
460
  union mysockaddr serveraddr;
424
461
  struct frec *forward;
425
 
  HEADER *header;
426
 
  union mysockaddr serveraddr;
427
462
  socklen_t addrlen = sizeof(serveraddr);
428
 
  ssize_t n = recvfrom(sfd->fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
 
463
  ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
429
464
  size_t nn;
430
 
 
 
465
  struct server *server;
 
466
  
431
467
  /* packet buffer overwritten */
432
468
  daemon->srv_save = NULL;
433
 
 
 
469
  
434
470
  /* Determine the address of the server replying  so that we can mark that as good */
435
 
  serveraddr.sa.sa_family = sfd->source_addr.sa.sa_family;
 
471
  serveraddr.sa.sa_family = family;
436
472
#ifdef HAVE_IPV6
437
473
  if (serveraddr.sa.sa_family == AF_INET6)
438
474
    serveraddr.in6.sin6_flowinfo = 0;
439
475
#endif
440
476
  
 
477
  /* spoof check: answer must come from known server, */
 
478
  for (server = daemon->servers; server; server = server->next)
 
479
    if (!(server->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR)) &&
 
480
        sockaddr_isequal(&server->addr, &serveraddr))
 
481
      break;
 
482
   
441
483
  header = (HEADER *)daemon->packet;
442
 
  forward = lookup_frec(ntohs(header->id));
443
 
  
444
 
  if (n >= (int)sizeof(HEADER) && header->qr && forward)
 
484
  
 
485
  if (!server ||
 
486
      n < (int)sizeof(HEADER) || !header->qr ||
 
487
      !(forward = lookup_frec(ntohs(header->id), questions_crc(header, n, daemon->namebuff))))
 
488
    return;
 
489
   
 
490
  server = forward->sentto;
 
491
  
 
492
  if ((header->rcode == SERVFAIL || header->rcode == REFUSED) &&
 
493
      !(daemon->options & OPT_ORDER) &&
 
494
      forward->forwardall == 0)
 
495
    /* for broken servers, attempt to send to another one. */
445
496
    {
446
 
       struct server *server = forward->sentto;
447
 
       
448
 
       if ((header->rcode == SERVFAIL || header->rcode == REFUSED) && forward->forwardall == 0)
449
 
         /* for broken servers, attempt to send to another one. */
450
 
         {
451
 
           unsigned char *pheader;
452
 
           size_t plen;
453
 
           
454
 
           /* recreate query from reply */
455
 
           pheader = find_pseudoheader(header, (size_t)n, &plen, NULL);
456
 
           header->ancount = htons(0);
457
 
           header->nscount = htons(0);
458
 
           header->arcount = htons(0);
459
 
           if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
460
 
             {
461
 
               header->qr = 0;
462
 
               header->tc = 0;
463
 
               forward_query(daemon, -1, NULL, NULL, 0, header, nn, now, forward);
464
 
               return;
465
 
             }
466
 
         }   
467
 
 
468
 
       if ((forward->sentto->flags & SERV_TYPE) == 0)
469
 
         {
470
 
           if (header->rcode == SERVFAIL || header->rcode == REFUSED)
471
 
             server = NULL;
472
 
           else
473
 
             {
474
 
               struct server *last_server;
475
 
               /* find good server by address if possible, otherwise assume the last one we sent to */ 
476
 
               for (last_server = daemon->servers; last_server; last_server = last_server->next)
477
 
                 if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
478
 
                     sockaddr_isequal(&last_server->addr, &serveraddr))
479
 
                   {
480
 
                     server = last_server;
481
 
                     break;
482
 
                   }
483
 
             } 
484
 
           daemon->last_server = server;
485
 
         }
486
 
                 
487
 
      /* If the answer is an error, keep the forward record in place in case
488
 
         we get a good reply from another server. Kill it when we've
489
 
         had replies from all to avoid filling the forwarding table when
490
 
         everything is broken */
491
 
      if (forward->forwardall == 0 || --forward->forwardall == 1 || 
492
 
          (header->rcode != REFUSED && header->rcode != SERVFAIL))
 
497
      unsigned char *pheader;
 
498
      size_t plen;
 
499
      int is_sign;
 
500
      
 
501
      /* recreate query from reply */
 
502
      pheader = find_pseudoheader(header, (size_t)n, &plen, NULL, &is_sign);
 
503
      if (!is_sign)
493
504
        {
494
 
          if ((nn = process_reply(daemon, header, now, forward->crc, server, (size_t)n)))
 
505
          header->ancount = htons(0);
 
506
          header->nscount = htons(0);
 
507
          header->arcount = htons(0);
 
508
          if ((nn = resize_packet(header, (size_t)n, pheader, plen)))
495
509
            {
496
 
              header->id = htons(forward->orig_id);
497
 
              header->ra = 1; /* recursion if available */
498
 
              send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn, 
499
 
                        &forward->source, &forward->dest, forward->iface);
 
510
              header->qr = 0;
 
511
              header->tc = 0;
 
512
              forward_query(-1, NULL, NULL, 0, header, nn, now, forward);
 
513
              return;
500
514
            }
501
 
          forward->new_id = 0; /* cancel */
502
 
        }
 
515
        }
 
516
    }   
 
517
  
 
518
  if ((forward->sentto->flags & SERV_TYPE) == 0)
 
519
    {
 
520
      if (header->rcode == SERVFAIL || header->rcode == REFUSED)
 
521
        server = NULL;
 
522
      else
 
523
        {
 
524
          struct server *last_server;
 
525
          
 
526
          /* find good server by address if possible, otherwise assume the last one we sent to */ 
 
527
          for (last_server = daemon->servers; last_server; last_server = last_server->next)
 
528
            if (!(last_server->flags & (SERV_LITERAL_ADDRESS | SERV_HAS_DOMAIN | SERV_FOR_NODOTS | SERV_NO_ADDR)) &&
 
529
                sockaddr_isequal(&last_server->addr, &serveraddr))
 
530
              {
 
531
                server = last_server;
 
532
                break;
 
533
              }
 
534
        } 
 
535
      if (!(daemon->options & OPT_ALL_SERVERS))
 
536
        daemon->last_server = server;
 
537
    }
 
538
  
 
539
  /* If the answer is an error, keep the forward record in place in case
 
540
     we get a good reply from another server. Kill it when we've
 
541
     had replies from all to avoid filling the forwarding table when
 
542
     everything is broken */
 
543
  if (forward->forwardall == 0 || --forward->forwardall == 1 || 
 
544
      (header->rcode != REFUSED && header->rcode != SERVFAIL))
 
545
    {
 
546
      if ((nn = process_reply(header, now, server, (size_t)n)))
 
547
        {
 
548
          header->id = htons(forward->orig_id);
 
549
          header->ra = 1; /* recursion if available */
 
550
          send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, nn, 
 
551
                    &forward->source, &forward->dest, forward->iface);
 
552
        }
 
553
      free_frec(forward); /* cancel */
503
554
    }
504
555
}
505
556
 
506
 
void receive_query(struct listener *listen, struct daemon *daemon, time_t now)
 
557
 
 
558
void receive_query(struct listener *listen, time_t now)
507
559
{
508
560
  HEADER *header = (HEADER *)daemon->packet;
509
561
  union mysockaddr source_addr;
523
575
#endif
524
576
#if defined(HAVE_LINUX_NETWORK)
525
577
    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
 
578
#elif defined(IP_RECVDSTADDR) && defined(HAVE_SOLARIS_NETWORK)
 
579
    char control[CMSG_SPACE(sizeof(struct in_addr)) +
 
580
                 CMSG_SPACE(sizeof(unsigned int))];
526
581
#elif defined(IP_RECVDSTADDR)
527
582
    char control[CMSG_SPACE(sizeof(struct in_addr)) +
528
583
                 CMSG_SPACE(sizeof(struct sockaddr_dl))];
590
645
            if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
591
646
              dst_addr_4 = dst_addr.addr.addr4 = *((struct in_addr *)CMSG_DATA(cmptr));
592
647
            else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
 
648
#ifdef HAVE_SOLARIS_NETWORK
 
649
              if_index = *((unsigned int *)CMSG_DATA(cmptr));
 
650
#else
593
651
              if_index = ((struct sockaddr_dl *)CMSG_DATA(cmptr))->sdl_index;
 
652
#endif
594
653
        }
595
654
#endif
596
655
      
611
670
      if (if_index == 0)
612
671
        return;
613
672
      
614
 
      if (daemon->if_except || daemon->if_names || (daemon->options & OPT_LOCALISE))
615
 
        {
616
673
#ifdef SIOCGIFNAME
617
 
          ifr.ifr_ifindex = if_index;
618
 
          if (ioctl(listen->fd, SIOCGIFNAME, &ifr) == -1)
619
 
            return;
 
674
      ifr.ifr_ifindex = if_index;
 
675
      if (ioctl(listen->fd, SIOCGIFNAME, &ifr) == -1)
 
676
        return;
620
677
#else
621
 
          if (!if_indextoname(if_index, ifr.ifr_name))
622
 
            return;
 
678
      if (!if_indextoname(if_index, ifr.ifr_name))
 
679
        return;
623
680
#endif
624
 
 
625
 
          if (listen->family == AF_INET &&
626
 
              (daemon->options & OPT_LOCALISE) &&
627
 
              ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
628
 
            return;
629
 
 
630
 
          netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
631
 
        }
632
 
 
633
 
      if (!iface_check(daemon, listen->family, &dst_addr, ifr.ifr_name))
634
 
        return;
 
681
      
 
682
      if (!iface_check(listen->family, &dst_addr, &ifr, &if_index))
 
683
        return;
 
684
      
 
685
      if (listen->family == AF_INET &&
 
686
          (daemon->options & OPT_LOCALISE) &&
 
687
          ioctl(listen->fd, SIOCGIFNETMASK, &ifr) == -1)
 
688
        return;
 
689
      
 
690
      netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
635
691
    }
636
692
  
637
693
  if (extract_request(header, (size_t)n, daemon->namebuff, &type))
638
694
    {
 
695
      char types[20];
 
696
 
 
697
      querystr(types, type);
 
698
 
639
699
      if (listen->family == AF_INET) 
640
700
        log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
641
 
                  (struct all_addr *)&source_addr.in.sin_addr, type, NULL, 0);
 
701
                  (struct all_addr *)&source_addr.in.sin_addr, types);
642
702
#ifdef HAVE_IPV6
643
703
      else
644
704
        log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
645
 
                  (struct all_addr *)&source_addr.in6.sin6_addr, type, NULL, 0);
 
705
                  (struct all_addr *)&source_addr.in6.sin6_addr, types);
646
706
#endif
647
707
    }
648
708
 
649
 
  m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n, daemon, 
 
709
  m = answer_request (header, ((char *) header) + PACKETSZ, (size_t)n, 
650
710
                      dst_addr_4, netmask, now);
651
711
  if (m >= 1)
652
 
    send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header, m, &source_addr, &dst_addr, if_index);
 
712
    {
 
713
      send_from(listen->fd, daemon->options & OPT_NOWILD, (char *)header, 
 
714
                m, &source_addr, &dst_addr, if_index);
 
715
      daemon->local_answer++;
 
716
    }
 
717
  else if (forward_query(listen->fd, &source_addr, &dst_addr, if_index,
 
718
                         header, (size_t)n, now, NULL))
 
719
    daemon->queries_forwarded++;
653
720
  else
654
 
    forward_query(daemon, listen->fd, &source_addr, &dst_addr, if_index,
655
 
                  header, (size_t)n, now, NULL);
 
721
    daemon->local_answer++;
656
722
}
657
723
 
658
724
/* The daemon forks before calling this: it should deal with one connection,
659
725
   blocking as neccessary, and then return. Note, need to be a bit careful
660
726
   about resources for debug mode, when the fork is suppressed: that's
661
727
   done by the caller. */
662
 
unsigned char *tcp_request(struct daemon *daemon, int confd, time_t now,
 
728
unsigned char *tcp_request(int confd, time_t now,
663
729
                           struct in_addr local_addr, struct in_addr netmask)
664
730
{
665
731
  int size = 0;
667
733
  unsigned short qtype, gotname;
668
734
  unsigned char c1, c2;
669
735
  /* Max TCP packet + slop */
670
 
  unsigned char *packet = malloc(65536 + MAXDNAME + RRFIXEDSZ);
 
736
  unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ);
671
737
  HEADER *header;
672
738
  struct server *last_server;
673
739
  
691
757
          
692
758
          if (getpeername(confd, (struct sockaddr *)&peer_addr, &peer_len) != -1)
693
759
            {
 
760
              char types[20];
 
761
 
 
762
              querystr(types, qtype);
 
763
 
694
764
              if (peer_addr.sa.sa_family == AF_INET) 
695
765
                log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, 
696
 
                          (struct all_addr *)&peer_addr.in.sin_addr, qtype, NULL, 0);
 
766
                          (struct all_addr *)&peer_addr.in.sin_addr, types);
697
767
#ifdef HAVE_IPV6
698
768
              else
699
769
                log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, 
700
 
                          (struct all_addr *)&peer_addr.in6.sin6_addr, qtype, NULL, 0);
 
770
                          (struct all_addr *)&peer_addr.in6.sin6_addr, types);
701
771
#endif
702
772
            }
703
773
        }
704
774
      
705
775
      /* m > 0 if answered from cache */
706
 
      m = answer_request(header, ((char *) header) + 65536, (unsigned int)size, daemon, 
 
776
      m = answer_request(header, ((char *) header) + 65536, (unsigned int)size, 
707
777
                         local_addr, netmask, now);
 
778
 
 
779
      /* Do this by steam now we're not in the select() loop */
 
780
      check_log_writer(NULL); 
708
781
      
709
782
      if (m == 0)
710
783
        {
714
787
          char *domain = NULL;
715
788
          
716
789
          if (gotname)
717
 
            flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain);
 
790
            flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain);
718
791
          
719
792
          if (type != 0  || (daemon->options & OPT_ORDER) || !daemon->last_server)
720
793
            last_server = daemon->servers;
749
822
                  
750
823
                  if ((last_server->tcpfd == -1) &&
751
824
                      (last_server->tcpfd = socket(last_server->addr.sa.sa_family, SOCK_STREAM, 0)) != -1 &&
752
 
                      connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1)
 
825
                      (!local_bind(last_server->tcpfd,  &last_server->source_addr, last_server->interface, 1) ||
 
826
                       connect(last_server->tcpfd, &last_server->addr.sa, sa_len(&last_server->addr)) == -1))
753
827
                    {
754
828
                      close(last_server->tcpfd);
755
829
                      last_server->tcpfd = -1;
757
831
                  
758
832
                  if (last_server->tcpfd == -1) 
759
833
                    continue;
760
 
                  
 
834
 
761
835
                  c1 = size >> 8;
762
836
                  c2 = size;
763
837
                  
771
845
                      last_server->tcpfd = -1;
772
846
                      continue;
773
847
                    } 
774
 
              
 
848
                  
775
849
                  m = (c1 << 8) | c2;
776
850
                  if (!read_write(last_server->tcpfd, packet, m, 1))
777
851
                    return packet;
780
854
                    strcpy(daemon->namebuff, "query");
781
855
                  if (last_server->addr.sa.sa_family == AF_INET)
782
856
                    log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, 
783
 
                              (struct all_addr *)&last_server->addr.in.sin_addr, 0, NULL, 0); 
 
857
                              (struct all_addr *)&last_server->addr.in.sin_addr, NULL); 
784
858
#ifdef HAVE_IPV6
785
859
                  else
786
860
                    log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, 
787
 
                              (struct all_addr *)&last_server->addr.in6.sin6_addr, 0, NULL, 0);
 
861
                              (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL);
788
862
#endif 
789
863
                  
790
864
                  /* There's no point in updating the cache, since this process will exit and
791
 
                     lose the information after one query. We make this call for the alias and 
 
865
                     lose the information after a few queries. We make this call for the alias and 
792
866
                     bogus-nxdomain side-effects. */
793
 
                  m = process_reply(daemon, header, now, crc, last_server, (unsigned int)m);
 
867
                  /* If the crc of the question section doesn't match the crc we sent, then
 
868
                     someone might be attempting to insert bogus values into the cache by 
 
869
                     sending replies containing questions and bogus answers. */
 
870
                  if (crc == questions_crc(header, (unsigned int)m, daemon->namebuff))
 
871
                    m = process_reply(header, now, last_server, (unsigned int)m);
794
872
                  
795
873
                  break;
796
874
                }
800
878
          if (m == 0)
801
879
            m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
802
880
        }
 
881
 
 
882
      check_log_writer(NULL);
803
883
      
804
884
      c1 = m>>8;
805
885
      c2 = m;
814
894
{
815
895
  struct frec *f;
816
896
  
817
 
  if ((f = (struct frec *)malloc(sizeof(struct frec))))
 
897
  if ((f = (struct frec *)whine_malloc(sizeof(struct frec))))
818
898
    {
819
 
      f->next = frec_list;
 
899
      f->next = daemon->frec_list;
820
900
      f->time = now;
821
 
      f->new_id = 0;
822
 
      frec_list = f;
 
901
      f->sentto = NULL;
 
902
      f->rfd4 = NULL;
 
903
#ifdef HAVE_IPV6
 
904
      f->rfd6 = NULL;
 
905
#endif
 
906
      daemon->frec_list = f;
823
907
    }
824
908
 
825
909
  return f;
826
910
}
827
911
 
 
912
static struct randfd *allocate_rfd(int family)
 
913
{
 
914
  static int finger = 0;
 
915
  int i;
 
916
 
 
917
  /* limit the number of sockets we have open to avoid starvation of 
 
918
     (eg) TFTP. Once we have a reasonable number, randomness should be OK */
 
919
 
 
920
  for (i = 0; i < RANDOM_SOCKS; i++)
 
921
    if (daemon->randomsocks[i].refcount == 0 && 
 
922
        (daemon->randomsocks[i].fd = random_sock(family)) != -1)
 
923
      {
 
924
        daemon->randomsocks[i].refcount = 1;
 
925
        daemon->randomsocks[i].family = family;
 
926
        return &daemon->randomsocks[i];
 
927
      }
 
928
 
 
929
  /* No free ones, grab an existing one */
 
930
  for (i = 0; i < RANDOM_SOCKS; i++)
 
931
    {
 
932
      int j = (i+finger) % RANDOM_SOCKS;
 
933
      if (daemon->randomsocks[j].family == family && daemon->randomsocks[j].refcount != 0xffff)
 
934
        {
 
935
          finger = j;
 
936
          daemon->randomsocks[j].refcount++;
 
937
          return &daemon->randomsocks[j];
 
938
        }
 
939
    }
 
940
 
 
941
  return NULL; /* doom */
 
942
}
 
943
 
 
944
static void free_frec(struct frec *f)
 
945
{
 
946
  if (f->rfd4 && --(f->rfd4->refcount) == 0)
 
947
    close(f->rfd4->fd);
 
948
    
 
949
  f->rfd4 = NULL;
 
950
  f->sentto = NULL;
 
951
  
 
952
#ifdef HAVE_IPV6
 
953
  if (f->rfd6 && --(f->rfd6->refcount) == 0)
 
954
    close(f->rfd6->fd);
 
955
    
 
956
  f->rfd6 = NULL;
 
957
#endif
 
958
}
 
959
 
828
960
/* if wait==NULL return a free or older than TIMEOUT record.
829
961
   else return *wait zero if one available, or *wait is delay to
830
 
   when the oldest in-use record will expire. */
831
 
struct frec *get_new_frec(struct daemon *daemon, time_t now, int *wait)
 
962
   when the oldest in-use record will expire. Impose an absolute
 
963
   limit of 4*TIMEOUT before we wipe things (for random sockets) */
 
964
struct frec *get_new_frec(time_t now, int *wait)
832
965
{
833
 
  struct frec *f, *oldest;
 
966
  struct frec *f, *oldest, *target;
834
967
  int count;
835
968
  
836
969
  if (wait)
837
970
    *wait = 0;
838
971
 
839
 
  for (f = frec_list, oldest = NULL, count = 0; f; f = f->next, count++)
840
 
    if (f->new_id == 0)
 
972
  for (f = daemon->frec_list, oldest = NULL, target =  NULL, count = 0; f; f = f->next, count++)
 
973
    if (!f->sentto)
 
974
      target = f;
 
975
    else 
841
976
      {
842
 
        f->time = now;
843
 
        return f;
 
977
        if (difftime(now, f->time) >= 4*TIMEOUT)
 
978
          {
 
979
            free_frec(f);
 
980
            target = f;
 
981
          }
 
982
        
 
983
        if (!oldest || difftime(f->time, oldest->time) <= 0)
 
984
          oldest = f;
844
985
      }
845
 
    else if (!oldest || difftime(f->time, oldest->time) <= 0)
846
 
      oldest = f;
 
986
 
 
987
  if (target)
 
988
    {
 
989
      target->time = now;
 
990
      return target;
 
991
    }
847
992
  
848
993
  /* can't find empty one, use oldest if there is one
849
994
     and it's older than timeout */
858
1003
 
859
1004
      if (!wait)
860
1005
        {
861
 
          oldest->new_id = 0;
 
1006
          free_frec(oldest);
862
1007
          oldest->time = now;
863
1008
        }
864
1009
      return oldest;
879
1024
  return f; /* OK if malloc fails and this is NULL */
880
1025
}
881
1026
 
882
 
static struct frec *lookup_frec(unsigned short id)
 
1027
/* crc is all-ones if not known. */
 
1028
static struct frec *lookup_frec(unsigned short id, unsigned int crc)
883
1029
{
884
1030
  struct frec *f;
885
1031
 
886
 
  for(f = frec_list; f; f = f->next)
887
 
    if (f->new_id == id)
 
1032
  for(f = daemon->frec_list; f; f = f->next)
 
1033
    if (f->sentto && f->new_id == id && 
 
1034
        (f->crc == crc || crc == 0xffffffff))
888
1035
      return f;
889
1036
      
890
1037
  return NULL;
896
1043
{
897
1044
  struct frec *f;
898
1045
  
899
 
  for(f = frec_list; f; f = f->next)
900
 
    if (f->new_id &&
 
1046
  for(f = daemon->frec_list; f; f = f->next)
 
1047
    if (f->sentto &&
901
1048
        f->orig_id == id && 
902
1049
        f->crc == crc &&
903
1050
        sockaddr_isequal(&f->source, addr))
907
1054
}
908
1055
 
909
1056
/* A server record is going away, remove references to it */
910
 
void server_gone(struct daemon *daemon, struct server *server)
 
1057
void server_gone(struct server *server)
911
1058
{
912
1059
  struct frec *f;
913
1060
  
914
 
  for (f = frec_list; f; f = f->next)
915
 
    if (f->new_id != 0 && f->sentto == server)
916
 
      f->new_id = 0;
 
1061
  for (f = daemon->frec_list; f; f = f->next)
 
1062
    if (f->sentto && f->sentto == server)
 
1063
      free_frec(f);
917
1064
  
918
1065
  if (daemon->last_server == server)
919
1066
    daemon->last_server = NULL;
922
1069
    daemon->srv_save = NULL;
923
1070
}
924
1071
 
925
 
/* return unique random ids between 1 and 65535 */
926
 
static unsigned short get_id(void)
 
1072
/* return unique random ids.
 
1073
   For signed packets we can't change the ID without breaking the
 
1074
   signing, so we keep the same one. In this case force is set, and this
 
1075
   routine degenerates into killing any conflicting forward record. */
 
1076
static unsigned short get_id(int force, unsigned short force_id, unsigned int crc)
927
1077
{
928
1078
  unsigned short ret = 0;
929
 
 
930
 
  while (ret == 0)
 
1079
  
 
1080
  if (force)
931
1081
    {
932
 
      ret = rand16();
933
 
      
934
 
      /* scrap ids already in use */
935
 
      if ((ret != 0) && lookup_frec(ret))
936
 
        ret = 0;
 
1082
      struct frec *f = lookup_frec(force_id, crc);
 
1083
      if (f)
 
1084
        free_frec(f); /* free */
 
1085
      ret = force_id;
937
1086
    }
938
 
 
 
1087
  else do 
 
1088
    ret = rand16();
 
1089
  while (lookup_frec(ret, crc));
 
1090
  
939
1091
  return ret;
940
1092
}
941
1093