~davewalker/ubuntu/oneiric/dnsmasq/add_dnsmasq-utils_package

« back to all changes in this revision

Viewing changes to src/network.c

  • Committer: Bazaar Package Importer
  • Author(s): Simon Kelley
  • Date: 2009-02-07 19:25:23 UTC
  • mfrom: (10.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090207192523-zut5qet639v1httx
 * Fix bashism in init script. (closes: #514397)
 * Tweak logging in init script.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* dnsmasq is Copyright (c) 2000-2007 Simon Kelley
 
1
/* dnsmasq is Copyright (c) 2000-2009 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
10
10
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
11
   GNU General Public License for more details.
12
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/>.
 
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/>.
15
15
*/
16
16
 
17
17
#include "dnsmasq.h"
366
366
{
367
367
  struct listener *listeners = NULL;
368
368
  struct irec *iface;
369
 
  int opt = 1;
370
 
  
 
369
  int rc, opt = 1;
 
370
#ifdef HAVE_IPV6
 
371
  static int dad_count = 0;
 
372
#endif
 
373
 
371
374
  for (iface = daemon->interfaces; iface; iface = iface->next)
372
375
    {
373
376
      struct listener *new = safe_malloc(sizeof(struct listener));
377
380
      new->tftpfd = -1;
378
381
      new->tcpfd = -1;
379
382
      new->fd = -1;
 
383
      listeners = new;
380
384
 
381
385
      if (daemon->port != 0)
382
386
        {
396
400
                die(_("failed to set IPV6 options on listening socket: %s"), NULL, EC_BADNET);
397
401
            }
398
402
#endif
 
403
 
 
404
          while(1)
 
405
            {
 
406
              if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1)
 
407
                break;
 
408
              
 
409
#ifdef HAVE_IPV6
 
410
              /* An interface may have an IPv6 address which is still undergoing DAD. 
 
411
                 If so, the bind will fail until the DAD completes, so we try over 20 seconds
 
412
                 before failing. */
 
413
              if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL) && 
 
414
                  dad_count++ < DAD_WAIT)
 
415
                {
 
416
                  sleep(1);
 
417
                  continue;
 
418
                }
 
419
#endif
 
420
              break;
 
421
            }
399
422
          
400
 
          if (bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1 ||
401
 
              bind(new->fd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
 
423
          if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1)
402
424
            {
403
 
#ifdef HAVE_IPV6
404
 
              if (iface->addr.sa.sa_family == AF_INET6 && (errno == ENODEV || errno == EADDRNOTAVAIL))
405
 
                {
406
 
                  close(new->tcpfd);
407
 
                  close(new->fd);
408
 
                  free(new);
409
 
                  new = NULL;
410
 
                }
411
 
              else
412
 
#endif
413
 
                {
414
 
                  prettyprint_addr(&iface->addr, daemon->namebuff);
415
 
                  die(_("failed to bind listening socket for %s: %s"), 
416
 
                      daemon->namebuff, EC_BADNET);
417
 
                }
 
425
              prettyprint_addr(&iface->addr, daemon->namebuff);
 
426
              die(_("failed to bind listening socket for %s: %s"), 
 
427
                  daemon->namebuff, EC_BADNET);
418
428
            }
419
 
          else if (listen(new->tcpfd, 5) == -1)
 
429
            
 
430
          if (listen(new->tcpfd, 5) == -1)
420
431
            die(_("failed to listen on socket: %s"), NULL, EC_BADNET);
421
432
        }
422
433
 
434
445
        }
435
446
#endif
436
447
 
437
 
      if (new)
438
 
        listeners = new;
439
448
    }
440
449
 
441
450
  return listeners;
442
451
}
443
452
 
444
453
 
445
 
/* return a UDP socket bound to a random port, have to coper with straying into
 
454
/* return a UDP socket bound to a random port, have to cope with straying into
446
455
   occupied port nos and reserved ones. */
447
456
int random_sock(int family)
448
457
{
452
461
    {
453
462
      union mysockaddr addr;
454
463
      unsigned int ports_avail = 65536u - (unsigned short)daemon->min_port;
455
 
      int i, tries = 3 * ports_avail;
456
 
 
457
 
      if (tries > 100)
458
 
        tries = 100;
 
464
      int tries = ports_avail < 30 ? 3 * ports_avail : 100;
459
465
 
460
466
      memset(&addr, 0, sizeof(addr));
461
467
      addr.sa.sa_family = family;
463
469
      /* don't loop forever if all ports in use. */
464
470
 
465
471
      if (fix_fd(fd))
466
 
        for (i = tries; i != 0; i--)
 
472
        while(tries--)
467
473
          {
468
474
            unsigned short port = rand16();
469
475
            
522
528
    return 0;
523
529
    
524
530
#if defined(SO_BINDTODEVICE)
525
 
  if (strlen(intname) != 0 &&
 
531
  if (intname[0] != 0 &&
526
532
      setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, intname, sizeof(intname)) == -1)
527
533
    return 0;
528
534
#endif
537
543
 
538
544
  /* when using random ports, servers which would otherwise use
539
545
     the INADDR_ANY/port0 socket have sfd set to NULL */
540
 
  if (!daemon->osport)
 
546
  if (!daemon->osport && intname[0] == 0)
541
547
    {
542
548
      errno = 0;
543
549
      
623
629
        (daemon->options & OPT_NOWILD))
624
630
      {
625
631
        prettyprint_addr(&srv->addr, daemon->namebuff);
626
 
        if (strlen(srv->interface) != 0)
 
632
        if (srv->interface[0] != 0)
627
633
          {
628
634
            strcat(daemon->namebuff, " ");
629
635
            strcat(daemon->namebuff, srv->interface);
698
704
          else if (!(new->flags & SERV_LITERAL_ADDRESS))
699
705
            my_syslog(LOG_INFO, _("using nameserver %s#%d for %s %s"), daemon->namebuff, port, s1, s2);
700
706
        }
701
 
      else if (strlen(new->interface) != 0)
 
707
      else if (new->interface[0] != 0)
702
708
        my_syslog(LOG_INFO, _("using nameserver %s#%d(via %s)"), daemon->namebuff, port, new->interface); 
703
709
      else
704
710
        my_syslog(LOG_INFO, _("using nameserver %s#%d"), daemon->namebuff, port);