~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to ntpd/ntp_intres.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2009-11-26 22:16:37 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20091126221637-lbtdp0ax1yg9t0bx
Tags: 1:4.2.4p7+dfsg-4
* Use uname -s instead of dpkg-architecture to found the kernel we're
  running on.  dpkg-architecture is part of dpkg-dev. (Closes: #558145)
* Make the package fail to build on hurd since it does not provided
  the needed system calls for ntpd to work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 * might go about autoconfiguring an NTP distribution network.
16
16
 *
17
17
 */
18
 
 /*
19
 
 * For special situations define the FORCE_DNSRETRY Macro
20
 
 * to force retries even if it fails the lookup.
21
 
 * Use with extreme caution since it will then retry forever.
22
 
 */
23
18
 
24
19
#ifdef HAVE_CONFIG_H
25
20
# include <config.h>
156
151
struct ntp_res_t_pkt {          /* Tagged packet: */
157
152
        void *tag;              /* For the caller */
158
153
        u_int32 paddr;          /* IP to look up, or 0 */
159
 
        char name[MAXHOSTNAMELEN]; /* Name to look up (if 1st byte is not 0) */
 
154
        char *name;             /* Name to look up (if 1st byte is not 0) */
160
155
};
161
156
 
162
157
struct ntp_res_c_pkt {          /* Control packet: */
163
 
        char name[MAXHOSTNAMELEN];
 
158
        char *name;
164
159
        u_int32 paddr;
165
160
        int mode;
166
161
        int version;
463
458
        struct conf_entry *entry
464
459
        )
465
460
{
 
461
        static int eai_again_seen = 0;
466
462
        struct addrinfo *addr;
467
463
        struct addrinfo hints;
 
464
        int again;
468
465
        int error;
469
466
 
470
467
        checkparent();          /* make sure our guy is still running */
475
472
                return 1;
476
473
        }
477
474
 
478
 
        if (entry->ce_name == NULL && SOCKNUL(&entry->peer_store)) {
 
475
        if (entry->ce_name == NULL && SOCKNUL(&entry->peer_store)) {
479
476
                msyslog(LOG_ERR, "findhostaddr: both ce_name and ce_peeraddr are undefined!");
480
477
                return 0;
481
478
        }
482
479
 
483
480
        if (entry->ce_name) {
484
 
#ifdef DEBUG
485
 
                if (debug > 2)
486
 
                        msyslog(LOG_INFO, "findhostaddr: Resolving <%s>",
487
 
                                entry->ce_name);
488
 
#endif /* DEBUG */
 
481
                DPRINTF(2, ("findhostaddr: Resolving <%s>\n",
 
482
                        entry->ce_name));
489
483
 
490
484
                memset(&hints, 0, sizeof(hints));
491
485
                hints.ai_family = AF_UNSPEC;
508
502
                                entry->ce_config.v6_flag = 1;
509
503
                        }
510
504
                }
511
 
                else if (error == EAI_NONAME)
512
 
                {
513
 
                        msyslog(LOG_ERR, "host name not found: %s", entry->ce_name);
514
 
                }
515
505
        } else {
516
 
#ifdef DEBUG
517
 
                if (debug > 2)
518
 
                        msyslog(LOG_INFO, "findhostaddr: Resolving %s>",
519
 
                                stoa(&entry->peer_store));
520
 
#endif
521
 
                entry->ce_name = emalloc(MAXHOSTNAMELEN);
 
506
                DPRINTF(2, ("findhostaddr: Resolving <%s>\n",
 
507
                        stoa(&entry->peer_store)));
 
508
 
 
509
                entry->ce_name = emalloc(NI_MAXHOST);
522
510
                error = getnameinfo((const struct sockaddr *)&entry->peer_store,
523
511
                                   SOCKLEN(&entry->peer_store),
524
 
                                   (char *)&entry->ce_name, MAXHOSTNAMELEN,
 
512
                                   (char *)&entry->ce_name, NI_MAXHOST,
525
513
                                   NULL, 0, 0);
526
514
        }
527
 
#ifdef DEBUG
528
 
        if (debug > 2)
529
 
                printf("intres: got error status of: %d\n", error);
530
 
#endif
531
 
 
532
 
        /*
533
 
         * If the resolver failed, see if the failure is
534
 
         * temporary. If so, return success.
535
 
         */
536
 
        if (error != 0) {
537
 
                switch (error)
538
 
                {
 
515
 
 
516
        if (0 == error) {
 
517
 
 
518
                /* again is our return value, for success it is 1 */
 
519
                again = 1;
 
520
 
 
521
                DPRINTF(2, ("findhostaddr: %s resolved.\n", 
 
522
                        (entry->ce_name) ? "name" : "address"));
 
523
        } else {
 
524
                /*
 
525
                 * If the resolver failed, see if the failure is
 
526
                 * temporary. If so, return success.
 
527
                 */
 
528
                again = 0;
 
529
 
 
530
                switch (error) {
 
531
 
 
532
                case EAI_FAIL:
 
533
                        again = 1;
 
534
                        break;
 
535
 
539
536
                case EAI_AGAIN:
540
 
                        return (1);
 
537
                        again = 1;
 
538
                        eai_again_seen = 1;
 
539
                        break;
 
540
 
541
541
                case EAI_NONAME:
542
 
#ifndef FORCE_DNSRETRY
543
 
                        return (0);
544
 
#else
545
 
                        return (1);
546
 
#endif
547
542
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
548
543
                case EAI_NODATA:
549
544
#endif
550
 
                case EAI_FAIL:
 
545
                        msyslog(LOG_ERR, "host name not found%s%s: %s",
 
546
                                (EAI_NONAME == error) ? "" : " EAI_NODATA",
 
547
                                (eai_again_seen) ? " (permanent)" : "",
 
548
                                entry->ce_name);
 
549
                        again = !eai_again_seen;
 
550
                        break;
 
551
 
551
552
#ifdef EAI_SYSTEM
552
553
                case EAI_SYSTEM:
553
 
                        return (1);
 
554
                        /* 
 
555
                         * EAI_SYSTEM means the real error is in errno.  We should be more
 
556
                         * discriminating about which errno values require retrying, but
 
557
                         * this matches existing behavior.
 
558
                         */
 
559
                        again = 1;
 
560
                        DPRINTF(1, ("intres: EAI_SYSTEM errno %d (%s) means try again, right?\n",
 
561
                                errno, strerror(errno)));
 
562
                        break;
554
563
#endif
555
 
                default:
556
 
                        return (0);
557
564
                }
558
 
        }
559
 
 
560
 
        if (entry->ce_name) {
561
 
#ifdef DEBUG
562
 
                if (debug > 2)
563
 
                        msyslog(LOG_INFO, "findhostaddr: name resolved.");
564
 
#endif
565
 
 
566
 
#ifdef DEBUG
567
 
                if (debug > 2)
568
 
                        msyslog(LOG_INFO, "findhostaddr: address resolved.");
569
 
#endif
570
 
        }
571
 
                   
572
 
        return (1);
 
565
 
 
566
                /* do this here to avoid perturbing errno earlier */
 
567
                DPRINTF(2, ("intres: got error status of: %d\n", error));
 
568
        }
 
569
 
 
570
        return again;
573
571
}
574
572
 
575
573
 
579
577
static void
580
578
openntp(void)
581
579
{
582
 
        struct addrinfo hints;
583
 
        struct addrinfo *addrResult;
584
 
        const char *localhost = "127.0.0.1";    /* Use IPv6 loopback */
 
580
        const char      *localhost = "127.0.0.1";       /* Use IPv4 loopback */
 
581
        struct addrinfo hints;
 
582
        struct addrinfo *addr;
 
583
        u_long          on;
 
584
        int             err;
585
585
 
586
586
        if (sockfd != INVALID_SOCKET)
587
 
            return;
 
587
                return;
588
588
 
589
589
        memset(&hints, 0, sizeof(hints));
590
590
 
592
592
         * For now only bother with IPv4
593
593
         */
594
594
        hints.ai_family = AF_INET;
595
 
 
596
595
        hints.ai_socktype = SOCK_DGRAM;
597
 
        if (getaddrinfo(localhost, "ntp", &hints, &addrResult)!=0) {
598
 
                msyslog(LOG_ERR, "getaddrinfo failed: %m");
 
596
 
 
597
        err = getaddrinfo(localhost, "ntp", &hints, &addr);
 
598
 
 
599
        if (err) {
 
600
#ifdef EAI_SYSTEM
 
601
                if (EAI_SYSTEM == err)
 
602
                        msyslog(LOG_ERR, "getaddrinfo(%s) failed: %m",
 
603
                                localhost);
 
604
                else
 
605
#endif
 
606
                        msyslog(LOG_ERR, "getaddrinfo(%s) failed: %s",
 
607
                                localhost, gai_strerror(err));
599
608
                resolver_exit(1);
600
609
        }
601
 
        sockfd = socket(addrResult->ai_family, addrResult->ai_socktype, 0);
602
 
 
603
 
        if (sockfd == -1) {
 
610
 
 
611
        sockfd = socket(addr->ai_family, addr->ai_socktype, 0);
 
612
 
 
613
        if (INVALID_SOCKET == sockfd) {
604
614
                msyslog(LOG_ERR, "socket() failed: %m");
605
615
                resolver_exit(1);
606
616
        }
607
617
 
 
618
#ifndef SYS_WINNT
 
619
        /*
 
620
         * On Windows only the count of sockets must be less than
 
621
         * FD_SETSIZE. On Unix each descriptor's value must be less
 
622
         * than FD_SETSIZE, as fd_set is a bit array.
 
623
         */
 
624
        if (sockfd >= FD_SETSIZE) {
 
625
                msyslog(LOG_ERR, "socket fd %d too large, FD_SETSIZE %d",
 
626
                        (int)sockfd, FD_SETSIZE);
 
627
                resolver_exit(1);
 
628
        }
 
629
 
608
630
        /*
609
631
         * Make the socket non-blocking.  We'll wait with select()
 
632
         * Unix: fcntl(O_NONBLOCK) or fcntl(FNDELAY)
610
633
         */
611
 
#ifndef SYS_WINNT
612
 
#if defined(O_NONBLOCK)
 
634
# ifdef O_NONBLOCK
613
635
        if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) {
614
636
                msyslog(LOG_ERR, "fcntl(O_NONBLOCK) failed: %m");
615
637
                resolver_exit(1);
616
638
        }
617
 
#else
618
 
#if defined(FNDELAY)
 
639
# else
 
640
#  ifdef FNDELAY
619
641
        if (fcntl(sockfd, F_SETFL, FNDELAY) == -1) {
620
642
                msyslog(LOG_ERR, "fcntl(FNDELAY) failed: %m");
621
643
                resolver_exit(1);
622
644
        }
623
 
#else
624
 
# include "Bletch: NEED NON BLOCKING IO"
625
 
#endif /* FNDDELAY */
626
 
#endif /* O_NONBLOCK */
627
 
#else  /* SYS_WINNT */
628
 
        {
629
 
                int on = 1;
630
 
                if (ioctlsocket(sockfd,FIONBIO,(u_long *) &on) == SOCKET_ERROR) {
631
 
                        msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
632
 
                        resolver_exit(1); /* Windows NT - set socket in non-blocking mode */
633
 
                }
 
645
#  else
 
646
#   include "Bletch: NEED NON BLOCKING IO"
 
647
#  endif        /* FNDDELAY */
 
648
# endif /* O_NONBLOCK */
 
649
        (void)on;       /* quiet unused warning */
 
650
#else   /* !SYS_WINNT above */
 
651
        /*
 
652
         * Make the socket non-blocking.  We'll wait with select()
 
653
         * Windows: ioctlsocket(FIONBIO)
 
654
         */
 
655
        on = 1;
 
656
        err = ioctlsocket(sockfd, FIONBIO, &on);
 
657
        if (SOCKET_ERROR == err) {
 
658
                msyslog(LOG_ERR, "ioctlsocket(FIONBIO) fails: %m");
 
659
                resolver_exit(1);
634
660
        }
635
661
#endif /* SYS_WINNT */
636
 
        if (connect(sockfd, addrResult->ai_addr, addrResult->ai_addrlen) == -1) {
 
662
 
 
663
        err = connect(sockfd, addr->ai_addr, addr->ai_addrlen);
 
664
        if (SOCKET_ERROR == err) {
637
665
                msyslog(LOG_ERR, "openntp: connect() failed: %m");
638
666
                resolver_exit(1);
639
667
        }
640
 
        freeaddrinfo(addrResult);
 
668
 
 
669
        freeaddrinfo(addr);
641
670
}
642
671
 
643
672
 
664
693
        checkparent();          /* make sure our guy is still running */
665
694
 
666
695
        if (sockfd == INVALID_SOCKET)
667
 
            openntp();
 
696
                openntp();
668
697
        
669
698
#ifdef SYS_WINNT
670
699
        hReadWriteEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
1110
1139
#endif
1111
1140
                if (dores && SOCKNUL(&(ce->peer_store))) {
1112
1141
                        if (!findhostaddr(ce)) {
 
1142
#ifndef IGNORE_DNS_ERRORS
1113
1143
                                msyslog(LOG_ERR,
1114
1144
                                        "couldn't resolve `%s', giving up on it",
1115
1145
                                        ce->ce_name);
1117
1147
                                ce = ceremove->ce_next;
1118
1148
                                removeentry(ceremove);
1119
1149
                                continue;
 
1150
#endif
1120
1151
                        }
1121
1152
                }
1122
1153