~ubuntu-branches/ubuntu/utopic/resiprocate/utopic

« back to all changes in this revision

Viewing changes to rutil/dns/ares/ares_init.c

  • Committer: Package Import Robot
  • Author(s): Daniel Pocock
  • Date: 2013-12-09 20:20:09 UTC
  • mfrom: (18.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20131209202009-p6cjqd9f5pjay7op
* New upstream release
* Enable DTLS support
* Enable repro plugins and ship repro headers in dev package

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
static int ip_addr(const char *s, int len, struct in_addr *addr);
76
76
static void natural_mask(struct apattern *pat);
77
77
static int find_server(struct server_state *servers, int nservers, struct in_addr addr);
78
 
static int get_physical_address(char *physicalAddr, int physicalAddrBufSz, int* physAddrLen, struct in_addr addr);
 
78
#ifdef USE_IPV6
 
79
static int find_server6(struct server_state *servers, int nservers, struct in6_addr addr);
 
80
#endif
79
81
 
80
82
static int      inet_pton4(const char *src, u_char *dst);
81
83
#ifdef USE_IPV6
250
252
  /* Copy the servers, if given. */
251
253
  if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1 && options->nservers>0 )
252
254
  {
253
 
     channel->servers =
254
 
        malloc(options->nservers * sizeof(struct server_state));
 
255
     channel->servers = malloc(options->nservers * sizeof(struct server_state));
255
256
     if (channel->servers == NULL)
256
257
        return ARES_ENOMEM;
257
258
     memset(channel->servers, '\0', options->nservers * sizeof(struct server_state));
258
259
     for (i = 0; i < options->nservers; i++)
259
260
     {
260
261
#ifdef USE_IPV6
261
 
            channel->servers[i].family = options->servers[i].family;
262
 
            if (options->servers[i].family == AF_INET6)
263
 
            {
264
 
               channel->servers[i].addr6 = options->servers[i].addr6;
265
 
            }
266
 
            else
267
 
            {
268
 
               assert( channel->servers[i].family == AF_INET );
269
 
                   channel->servers[i].addr = options->servers[i].addr;
270
 
            }
271
 
#else     
272
 
            channel->servers[i].addr = options->servers[i];
 
262
       channel->servers[i].family = options->servers[i].family;
 
263
       if (options->servers[i].family == AF_INET6)
 
264
       {
 
265
         channel->servers[i].addr6 = options->servers[i].addr6;
 
266
       }
 
267
       else
 
268
       {
 
269
         assert( channel->servers[i].family == AF_INET );
 
270
         channel->servers[i].addr = options->servers[i].addr;
 
271
       }
 
272
#else
 
273
       channel->servers[i].addr = options->servers[i];
273
274
#endif
274
275
     }
275
276
     channel->nservers = options->nservers;
398
399
}
399
400
 
400
401
#if defined(__APPLE__) || defined(__MACH__)
401
 
static void init_by_defaults_systemconfiguration(ares_channel channel)
 
402
static void init_by_defaults_apple_nameservers(ares_channel channel)
402
403
{
403
404
  SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};
404
405
  SCDynamicStoreRef store = 0;
407
408
  // .amr. iPhone/iOS SDK's don't support SCDynamicStoreCreate so in that case fall back
408
409
  // to the nservers=0 case.
409
410
#ifndef TARGET_OS_IPHONE
410
 
  store = SCDynamicStoreCreate(NULL, CFSTR("init_by_defaults_systemconfiguration"), NULL, &context);
 
411
  store = SCDynamicStoreCreate(NULL, CFSTR("init_by_defaults_apple_nameservers"), NULL, &context);
411
412
 
412
413
  if (store)
413
414
  {
447
448
    CFRelease(store);
448
449
  }
449
450
#endif // TARGET_OS_IPHONE
450
 
 
451
 
  /* If no specified servers, try a local named. */
452
 
  if (channel->nservers == 0)
453
 
  {
454
 
    channel->servers = malloc(sizeof(struct server_state));
455
 
    memset(channel->servers, '\0', sizeof(struct server_state));
456
 
                
457
 
#ifdef USE_IPV6                  
458
 
    channel->servers[0].family = AF_INET;
459
 
#endif
460
 
                
461
 
    channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
462
 
    channel->servers[0].default_localhost_server = 1;
463
 
    channel->nservers = 1;
464
 
  }
 
451
}
 
452
#endif
 
453
 
 
454
#if defined(__ANDROID__)
 
455
static int init_by_defaults_andriod_nameservers(ares_channel channel)
 
456
{
 
457
   int android_prop_found = 0;
 
458
   char props_dns[2][PROP_VALUE_MAX];
 
459
   char prop_name[PROP_NAME_MAX];
 
460
   const char *prop_keys[2] = { "net.dns1", "net.dns2" };
 
461
   int i = 0, j = 0;
 
462
 
 
463
   for(i = 0; i < 2; i++)
 
464
   {
 
465
      props_dns[android_prop_found][0] = 0;
 
466
      const prop_info *prop = __system_property_find(prop_keys[i]);
 
467
      if(prop != NULL)
 
468
      {
 
469
         __system_property_read(prop, NULL, props_dns[android_prop_found]);
 
470
         if(props_dns[android_prop_found][0] != 0)
 
471
            android_prop_found++;
 
472
      }
 
473
   }
 
474
   if(android_prop_found > 0)
 
475
   {
 
476
      channel->servers = malloc( (android_prop_found) * sizeof(struct server_state));
 
477
      if (!channel->servers)
 
478
      {
 
479
         return ARES_ENOMEM;
 
480
      }
 
481
      memset(channel->servers, '\0', android_prop_found * sizeof(struct server_state));
 
482
 
 
483
      for(i = 0; i < android_prop_found; i++)
 
484
      {
 
485
         int rc = inet_pton(AF_INET, props_dns[i], &channel->servers[j].addr.s_addr);
 
486
         if(rc == 1)
 
487
         {
 
488
#ifdef USE_IPV6
 
489
            channel->servers[j].family = AF_INET;
 
490
#endif
 
491
            j++;
 
492
         }
 
493
#ifdef USE_IPV6
 
494
         else
 
495
         {
 
496
            rc = inet_pton(AF_INET6, props_dns[i], &channel->servers[j].addr6.s_addr);
 
497
            if(rc == 1)
 
498
            {
 
499
               channel->servers[j].family = AF_INET6;
 
500
               j++;
 
501
            }
 
502
         }
 
503
#endif
 
504
      }
 
505
      // how many really are valid IP addresses?
 
506
      channel->nservers = j;
 
507
   }
 
508
   return ARES_SUCCESS;
 
509
}
 
510
#endif
 
511
 
 
512
#ifdef WIN32
 
513
static int init_by_defaults_windows_nameservers_getadaptersaddresses(ares_channel channel)
 
514
{
 
515
   DWORD (WINAPI * GetAdaptersAddressesProc)(ULONG, DWORD, VOID *, IP_ADAPTER_ADDRESSES *, ULONG *);
 
516
   HANDLE hLib = 0;
 
517
   DWORD dwRet = ERROR_BUFFER_OVERFLOW;
 
518
   DWORD dwSize = 0;
 
519
   int trys = 0;
 
520
   IP_ADAPTER_ADDRESSES *pAdapterAddresses = 0;
 
521
   int rc = ARES_ENOTFOUND;
 
522
   int loopnum = 0;
 
523
   int numreturned = 0;
 
524
 
 
525
   hLib = LoadLibrary(TEXT("iphlpapi.dll"));
 
526
   if (!hLib)
 
527
   {
 
528
      return ARES_ENOTIMP;
 
529
   }
 
530
 
 
531
   (void*)GetAdaptersAddressesProc = GetProcAddress(hLib, TEXT("GetAdaptersAddresses"));
 
532
   if(!GetAdaptersAddressesProc)
 
533
   {
 
534
      rc = ARES_ENOTIMP;
 
535
      goto cleanup;
 
536
   }
 
537
 
 
538
   // Allocate 15kb of buffer to avoid calling twice - recommended in MSDN
 
539
   dwSize = 15 * 1024;
 
540
   pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) malloc(dwSize);
 
541
   if(!pAdapterAddresses)
 
542
   {
 
543
      rc = ARES_ENOMEM;
 
544
      goto cleanup;
 
545
   }
 
546
 
 
547
   while(ERROR_BUFFER_OVERFLOW == (dwRet = GetAdaptersAddressesProc( AF_UNSPEC, 0, NULL, pAdapterAddresses, &dwSize )) && trys++ < 5)
 
548
   {
 
549
      pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) realloc(pAdapterAddresses, dwSize);
 
550
      if(!pAdapterAddresses)
 
551
      {
 
552
         rc = ARES_ENOMEM;
 
553
         goto cleanup;
 
554
      }
 
555
   }
 
556
   if( dwRet != 0)
 
557
   {
 
558
      rc = ARES_ENODATA;
 
559
      goto cleanup;
 
560
   }
 
561
 
 
562
   // We have some data - process it
 
563
   // We walk the data twice - the first time is to figure out how many DNS servers there are so that we can allocate
 
564
   // the channel memory.  Note:  If there are duplicates we may end up allocating more memory than we use - but that is fine.
 
565
   // The seconds walk through the data we add the actual DNS servers to the channel structure
 
566
   while(++loopnum <= 2)
 
567
   {
 
568
      IP_ADAPTER_ADDRESSES * AI = NULL;
 
569
 
 
570
      // If this is the 2nd lap through the loop we now know the amount of memory to allocate: 
 
571
      // enough for numreturned dns servers
 
572
      if(loopnum == 2)
 
573
      {
 
574
         if(numreturned == 0)
 
575
         {
 
576
            rc = ARES_ENODATA;
 
577
            goto cleanup;
 
578
         }
 
579
 
 
580
         channel->servers = malloc( (numreturned) * sizeof(struct server_state));
 
581
         if (!channel->servers)
 
582
         {
 
583
            rc = ARES_ENOMEM;
 
584
            goto cleanup;
 
585
         }
 
586
         memset(channel->servers, '\0', numreturned * sizeof(struct server_state));
 
587
         channel->nservers = 0;
 
588
      }
 
589
 
 
590
      // Process each adapter
 
591
      for (AI = pAdapterAddresses; AI != NULL; AI = AI->Next)
 
592
      {
 
593
         PIP_ADAPTER_DNS_SERVER_ADDRESS dnsServers = AI->FirstDnsServerAddress;
 
594
 
 
595
         if(AI->IfType == IF_TYPE_TUNNEL || AI->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
 
596
         {
 
597
            // Don't process TUNNEL or LOOPBACK adapters
 
598
            continue;
 
599
         }
 
600
 
 
601
         // Process each DNS server for the adapter
 
602
         for (; dnsServers; dnsServers = dnsServers->Next)
 
603
         {
 
604
            // Safety check for null sockaddr - shouldn't happen
 
605
            if (! dnsServers->Address.lpSockaddr)
 
606
            {
 
607
               continue;
 
608
            }
 
609
 
 
610
            if (dnsServers->Address.lpSockaddr->sa_family == AF_INET)
 
611
            {
 
612
               struct sockaddr_in *sa4 = (struct sockaddr_in *)dnsServers->Address.lpSockaddr;
 
613
               if((sa4->sin_addr.S_un.S_addr != INADDR_ANY) && (sa4->sin_addr.S_un.S_addr != INADDR_NONE))
 
614
               {
 
615
                  if(loopnum == 1)
 
616
                  {
 
617
                     numreturned++;
 
618
                  }
 
619
                  else
 
620
                  {
 
621
                     // add v4 server if it doesn't exist already
 
622
                     if (find_server(channel->servers, channel->nservers, sa4->sin_addr) == -1)
 
623
                     {
 
624
                        // printf( "ARES: %s\n", inet_ntop(sa4->sin_addr) );
 
625
#ifdef USE_IPV6
 
626
                        channel->servers[ channel->nservers ].family = AF_INET;
 
627
#endif
 
628
                        channel->servers[channel->nservers].addr = sa4->sin_addr;
 
629
 
 
630
                        // Copy over physical address for use in ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3 mode
 
631
                        if (AI->PhysicalAddressLength <= sizeof(channel->servers[channel->nservers].physical_addr))
 
632
                        {
 
633
                           channel->servers[channel->nservers].physical_addr_len = AI->PhysicalAddressLength;
 
634
                           memcpy(channel->servers[channel->nservers].physical_addr, &AI->PhysicalAddress[0], AI->PhysicalAddressLength);
 
635
                        }
 
636
                        channel->nservers++;
 
637
                     }
 
638
                  }
 
639
               }
 
640
            }
 
641
#ifdef USE_IPV6
 
642
            else if(dnsServers->Address.lpSockaddr->sa_family == AF_INET6)
 
643
            {
 
644
               struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)dnsServers->Address.lpSockaddr;
 
645
               if (memcmp(&sa6->sin6_addr, &in6addr_any, sizeof(sa6->sin6_addr)) != 0)
 
646
               {
 
647
                  if(loopnum == 1)
 
648
                  {
 
649
                     numreturned++;
 
650
                  }
 
651
                  else
 
652
                  {
 
653
                     // add v6 server if it doesn't exist already
 
654
                     if (find_server6(channel->servers, channel->nservers, sa6->sin6_addr) == -1)
 
655
                     {
 
656
                        // printf( "ARES: %s\n", inet_ntop6(sa6->sin6_addr) );
 
657
                        channel->servers[ channel->nservers ].family = AF_INET6;
 
658
                        memcpy(&channel->servers[channel->nservers].addr6, &sa6->sin6_addr, sizeof(channel->servers[channel->nservers].addr6));
 
659
 
 
660
                        // Copy over physical address for use in ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3 mode
 
661
                        if (AI->PhysicalAddressLength <= sizeof(channel->servers[channel->nservers].physical_addr))
 
662
                        {
 
663
                           channel->servers[channel->nservers].physical_addr_len = AI->PhysicalAddressLength;
 
664
                           memcpy(channel->servers[channel->nservers].physical_addr, &AI->PhysicalAddress[0], AI->PhysicalAddressLength);
 
665
                        }
 
666
                        channel->nservers++;
 
667
                     }
 
668
                  }
 
669
               }
 
670
            }
 
671
#endif
 
672
         }
 
673
      }
 
674
   }
 
675
 
 
676
cleanup:
 
677
   if (pAdapterAddresses)
 
678
   {
 
679
      free(pAdapterAddresses);
 
680
   }
 
681
   if (hLib)
 
682
   {
 
683
      FreeLibrary(hLib);
 
684
   }
 
685
   return rc;
 
686
}
 
687
 
 
688
static int init_by_defaults_windows_nameservers_getnetworkparams(ares_channel channel)
 
689
{
 
690
   /*
 
691
   * Way of getting nameservers that should work on all Windows from 98 / Server 2000 and on.  Doesn't support IPv6 nameservers.
 
692
   */
 
693
   FIXED_INFO *     FixedInfo = NULL;
 
694
   ULONG            ulOutBufLen = 0;
 
695
   DWORD            dwRetVal;
 
696
   IP_ADDR_STRING * pIPAddr;
 
697
   HANDLE           hLib;
 
698
   int              num;
 
699
   int              trys = 0;
 
700
   DWORD (WINAPI *GetNetworkParamsProc)(FIXED_INFO*, DWORD*); 
 
701
 
 
702
   hLib = LoadLibrary(TEXT("iphlpapi.dll"));
 
703
   if(!hLib)
 
704
   {
 
705
      return ARES_ENOTIMP;
 
706
   }
 
707
 
 
708
   (void*)GetNetworkParamsProc = GetProcAddress(hLib, TEXT("GetNetworkParams"));
 
709
   if(!GetNetworkParamsProc)
 
710
   {
 
711
      FreeLibrary(hLib);
 
712
      return ARES_ENOTIMP;
 
713
   }
 
714
   //printf("ARES: figuring out DNS servers\n");
 
715
   while(ERROR_BUFFER_OVERFLOW == (dwRetVal = GetNetworkParamsProc( FixedInfo, &ulOutBufLen )) && trys++ < 5)
 
716
   {
 
717
      if(FixedInfo != NULL)
 
718
      {
 
719
         GlobalFree( FixedInfo );
 
720
      }
 
721
      FixedInfo = (FIXED_INFO *)GlobalAlloc( GPTR, ulOutBufLen );
 
722
   }
 
723
   if( dwRetVal != 0)
 
724
   {
 
725
      //printf("ARES: couldn't get network params, dwRet=0x%x\n", dwRetVal);
 
726
      if(FixedInfo != NULL)
 
727
      {
 
728
         GlobalFree( FixedInfo );
 
729
      }
 
730
      FreeLibrary(hLib);
 
731
      return ARES_ENODATA;
 
732
   }
 
733
 
 
734
   /**
 
735
   printf( "Host Name: %s\n", FixedInfo -> HostName );
 
736
   printf( "Domain Name: %s\n", FixedInfo -> DomainName );
 
737
   printf( "DNS Servers:\n" );
 
738
   printf( "\t%s\n", FixedInfo -> DnsServerList.IpAddress.String );
 
739
   **/
 
740
 
 
741
   // Count how many nameserver entries we have and allocate memory for them.
 
742
   num = 0;
 
743
   pIPAddr = &FixedInfo->DnsServerList;     
 
744
   while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0)
 
745
   {
 
746
      num++;
 
747
      pIPAddr = pIPAddr ->Next;
 
748
   }
 
749
   //if(num == 0)
 
750
   //{
 
751
   //    printf("ARES: no nameservers! size=%d\n", ulOutBufLen);
 
752
   //}
 
753
   //else
 
754
   //{
 
755
   //    printf("ARES: num nameservers: %d, size=%d\n", num, ulOutBufLen);
 
756
   //}
 
757
   if(num>0)
 
758
   {
 
759
      channel->servers = malloc( (num) * sizeof(struct server_state));
 
760
      if (!channel->servers)
 
761
      {
 
762
         GlobalFree( FixedInfo );
 
763
         FreeLibrary(hLib);
 
764
         return ARES_ENOMEM;
 
765
      }
 
766
      memset(channel->servers, '\0', num * sizeof(struct server_state));
 
767
 
 
768
      channel->nservers = 0;
 
769
      pIPAddr = &FixedInfo->DnsServerList;   
 
770
      while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0)
 
771
      {
 
772
         struct in_addr addr;
 
773
         addr.s_addr = inet_addr(pIPAddr->IpAddress.String);
 
774
         // append unique only
 
775
         if (find_server(channel->servers, channel->nservers, addr) == -1)
 
776
         {
 
777
            // printf( "ARES: %s\n", pIPAddr ->IpAddress.String );
 
778
#ifdef USE_IPV6
 
779
            channel->servers[ channel->nservers ].family = AF_INET;
 
780
#endif
 
781
            channel->servers[channel->nservers].addr = addr;
 
782
            channel->nservers++;
 
783
         }
 
784
 
 
785
         pIPAddr = pIPAddr ->Next;
 
786
      }
 
787
      //printf("ARES: got all %d nameservers\n",num);
 
788
   }
 
789
 
 
790
   GlobalFree( FixedInfo );
 
791
   FreeLibrary(hLib);
 
792
 
 
793
   return ARES_SUCCESS;
465
794
}
466
795
#endif
467
796
 
468
797
static int init_by_defaults(ares_channel channel)
469
798
{
470
 
  char hostname[MAXHOSTNAMELEN + 1];
471
 
 
472
 
  if (channel->flags == -1)
473
 
    channel->flags = 0;
474
 
  if (channel->timeout == -1)
475
 
    channel->timeout = DEFAULT_TIMEOUT;
476
 
  if (channel->tries == -1)
477
 
    channel->tries = DEFAULT_TRIES;
478
 
  if (channel->ndots == -1)
479
 
    channel->ndots = 1;
480
 
  if (channel->udp_port == -1)
481
 
    channel->udp_port = htons(NAMESERVER_PORT);
482
 
  if (channel->tcp_port == -1)
483
 
    channel->tcp_port = htons(NAMESERVER_PORT);
484
 
 
485
 
  if (channel->nservers == -1)
486
 
    {
 
799
   char hostname[MAXHOSTNAMELEN + 1];
 
800
 
 
801
   if (channel->flags == -1)
 
802
      channel->flags = 0;
 
803
   if (channel->timeout == -1)
 
804
      channel->timeout = DEFAULT_TIMEOUT;
 
805
   if (channel->tries == -1)
 
806
      channel->tries = DEFAULT_TRIES;
 
807
   if (channel->ndots == -1)
 
808
      channel->ndots = 1;
 
809
   if (channel->udp_port == -1)
 
810
      channel->udp_port = htons(NAMESERVER_PORT);
 
811
   if (channel->tcp_port == -1)
 
812
      channel->tcp_port = htons(NAMESERVER_PORT);
 
813
 
 
814
   if (channel->nservers == -1)
 
815
   {
 
816
      // OS Specific Inits for nameservers
487
817
#ifdef WIN32
488
 
     /*
489
 
      * Way of getting nameservers that should work on all Windows from 98 on.
490
 
      */
491
 
      FIXED_INFO *     FixedInfo = NULL;
492
 
      ULONG            ulOutBufLen = 0;
493
 
      DWORD            dwRetVal;
494
 
      IP_ADDR_STRING * pIPAddr;
495
 
          HANDLE           hLib;
496
 
          int              num;
497
 
      int              trys = 0;
498
 
          DWORD (WINAPI *GetNetworkParams)(FIXED_INFO*, DWORD*); 
499
 
 
500
 
          hLib = LoadLibrary(TEXT("iphlpapi.dll"));
501
 
          if(!hLib)
502
 
          {
503
 
                  return ARES_ENOTIMP;
504
 
          }
505
 
 
506
 
          (void*)GetNetworkParams = GetProcAddress(hLib, TEXT("GetNetworkParams"));
507
 
          if(!GetNetworkParams)
508
 
          {
509
 
                  FreeLibrary(hLib);
510
 
                  return ARES_ENOTIMP;
511
 
          }
512
 
      //printf("ARES: figuring out DNS servers\n");
513
 
      while(ERROR_BUFFER_OVERFLOW == (dwRetVal = GetNetworkParams( FixedInfo, &ulOutBufLen )) && trys++ < 5)
514
 
      {
515
 
        if(FixedInfo != NULL)
516
 
        {
517
 
            GlobalFree( FixedInfo );
518
 
        }
519
 
        FixedInfo = (FIXED_INFO *)GlobalAlloc( GPTR, ulOutBufLen );
520
 
      }
521
 
      if( dwRetVal != 0)
522
 
      {
523
 
        //printf("ARES: couldn't get network params, dwRet=0x%x\n", dwRetVal);
524
 
        if(FixedInfo != NULL)
525
 
        {
526
 
            GlobalFree( FixedInfo );
527
 
        }
528
 
        FreeLibrary(hLib);
529
 
        return ARES_ENODATA;
530
 
      }
531
 
      else
532
 
      {
533
 
       /**
534
 
        printf( "Host Name: %s\n", FixedInfo -> HostName );
535
 
        printf( "Domain Name: %s\n", FixedInfo -> DomainName );
536
 
        printf( "DNS Servers:\n" );
537
 
        printf( "\t%s\n", FixedInfo -> DnsServerList.IpAddress.String );
538
 
        **/
539
 
 
540
 
        // Count how many nameserver entries we have and allocate memory for them.
541
 
        num = 0;
542
 
        pIPAddr = &FixedInfo->DnsServerList;     
543
 
        while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0)
544
 
        {
545
 
          num++;
546
 
          pIPAddr = pIPAddr ->Next;
547
 
        }
548
 
        //if(num == 0)
549
 
        //{
550
 
        //    printf("ARES: no nameservers! size=%d\n", ulOutBufLen);
551
 
        //}
552
 
        //else
553
 
        //{
554
 
        //    printf("ARES: num nameservers: %d, size=%d\n", num, ulOutBufLen);
555
 
        //}
556
 
        if(num>0)
557
 
        {
558
 
           channel->servers = malloc( (num) * sizeof(struct server_state));
559
 
                   if (!channel->servers)
560
 
                   {
561
 
                   GlobalFree( FixedInfo );
562
 
                       FreeLibrary(hLib);
563
 
                           return ARES_ENOMEM;
564
 
                   }
565
 
           memset(channel->servers, '\0', num * sizeof(struct server_state));
566
 
 
567
 
                   channel->nservers = 0;
568
 
           pIPAddr = &FixedInfo->DnsServerList;   
569
 
           while ( pIPAddr && strlen(pIPAddr->IpAddress.String) > 0)
570
 
                   {
571
 
             struct in_addr addr;
572
 
             addr.s_addr = inet_addr(pIPAddr->IpAddress.String);
573
 
             // append unique only
574
 
             if (find_server(channel->servers, channel->nservers, addr) == -1)
575
 
             {
576
 
                // printf( "ARES: %s\n", pIPAddr ->IpAddress.String );
577
 
#ifdef USE_IPV6                  
578
 
                channel->servers[ channel->nservers ].family = AF_INET;
579
 
#endif
580
 
                channel->servers[channel->nservers].addr = addr;
581
 
                if ((channel->flags & ARES_FLAG_TRY_NEXT_SERVER_ON_RCODE3))
582
 
                {
583
 
                   get_physical_address(channel->servers[channel->nservers].physical_addr,
584
 
                                        MAX_ADAPTER_ADDRESS_LENGTH,
585
 
                                        &channel->servers[channel->nservers].physical_addr_len,
586
 
                                        addr);
587
 
                }
588
 
                               channel->nservers++;
589
 
             }
590
 
 
591
 
             pIPAddr = pIPAddr ->Next;
592
 
           }
593
 
           //printf("ARES: got all %d nameservers\n",num);
594
 
        }
595
 
        else
596
 
        {
597
 
                   /* If no specified servers, try a local named. */
598
 
                   channel->servers = malloc(sizeof(struct server_state));
599
 
                   if (!channel->servers)
600
 
              return ARES_ENOMEM;
601
 
           memset(channel->servers, '\0', sizeof(struct server_state));
602
 
 
603
 
#ifdef USE_IPV6                  
604
 
           channel->servers[0].family = AF_INET;
605
 
#endif
606
 
 
607
 
                   channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
608
 
           channel->servers[0].default_localhost_server = 1;
609
 
                   channel->nservers = 1;
610
 
        }
611
 
 
612
 
        GlobalFree( FixedInfo );
613
 
            FreeLibrary(hLib);
614
 
          }
 
818
      if(init_by_defaults_windows_nameservers_getadaptersaddresses(channel) == ARES_ENOMEM)
 
819
      {
 
820
         return ARES_ENOMEM;
 
821
      }
 
822
      if (channel->nservers <= 0)
 
823
      {
 
824
         // If GetAdaptersAddresses approach didn't work then try GetNetworkParams (non IPv6 compatible)
 
825
         if(init_by_defaults_windows_nameservers_getnetworkparams(channel) == ARES_ENOMEM)
 
826
         {
 
827
            return ARES_ENOMEM;
 
828
         }
 
829
      }
615
830
#elif defined(__APPLE__) || defined(__MACH__)
616
 
      init_by_defaults_systemconfiguration(channel);
 
831
      init_by_defaults_apple_nameservers(channel);
617
832
#elif defined(__ANDROID__)
618
 
      int android_prop_found = 0;
619
 
      char props_dns[2][PROP_VALUE_MAX];
620
 
      char prop_name[PROP_NAME_MAX];
621
 
      const char *prop_keys[2] = { "net.dns1", "net.dns2" };
622
 
      int i = 0, j = 0;
623
 
      for(i = 0; i < 2; i++)
624
 
        {
625
 
          props_dns[android_prop_found][0] = 0;
626
 
          const prop_info *prop = __system_property_find(prop_keys[i]);
627
 
          if(prop != NULL)
628
 
            {
629
 
              __system_property_read(prop, NULL, props_dns[android_prop_found]);
630
 
              if(props_dns[android_prop_found][0] != 0)
631
 
                android_prop_found++;
632
 
            }
633
 
        }
634
 
      if(android_prop_found > 0)
635
 
        {
636
 
          channel->servers = malloc( (android_prop_found) * sizeof(struct server_state));
637
 
          if (!channel->servers)
638
 
            {
639
 
              return ARES_ENOMEM;
640
 
            }
641
 
          memset(channel->servers, '\0', android_prop_found * sizeof(struct server_state));
642
 
 
643
 
          for(i = 0; i < android_prop_found; i++)
644
 
            {
645
 
              int rc = inet_pton(AF_INET, props_dns[i], &channel->servers[j].addr.s_addr);
646
 
              if(rc == 1)
647
 
                {
648
 
#ifdef USE_IPV6
649
 
                  channel->servers[j].family = AF_INET;
650
 
#endif
651
 
                  j++;
652
 
                }
653
 
#ifdef USE_IPV6
654
 
              else
655
 
                {
656
 
                  rc = inet_pton(AF_INET6, props_dns[i], &channel->servers[j].addr6.s_addr);
657
 
                  if(rc == 1)
658
 
                    {
659
 
                      channel->servers[j].family = AF_INET6;
660
 
                      j++;
661
 
                    }
662
 
                }
663
 
#endif
664
 
            }
665
 
          // how many really are valid IP addresses?
666
 
          channel->nservers = j;
667
 
        }
668
 
#else
669
 
                /* If nobody specified servers, try a local named. */
670
 
                channel->servers = malloc(sizeof(struct server_state));
671
 
                if (!channel->servers)
672
 
                        return ARES_ENOMEM;
673
 
        memset(channel->servers, '\0', sizeof(struct server_state));
674
 
 
675
 
                // need a way to test here if v4 or v6 is running
676
 
                // if v4 is running...
677
 
                channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
678
 
        channel->servers[0].default_localhost_server = 1;
679
 
#ifdef USE_IPV6             
680
 
        channel->servers[0].family = AF_INET;
681
 
#endif
682
 
                // if v6 is running...
683
 
        //      channel->servers[0].addr6.s_addr = htonl6(IN6ADDR_LOOPBACK_INIT);
684
 
#ifdef USE_IPV6             
685
 
        // channel->servers[0].family = AF_INET6;
686
 
#endif
687
 
 
688
 
                // hard to decide if there is one server or two here
689
 
                channel->nservers = 1;
690
 
#endif
691
 
    
692
 
    }
693
 
 
694
 
  if (channel->ndomains == -1)
695
 
    {
 
833
      if(init_by_defaults_andriod_nameservers(channel) == ARES_ENOMEM)
 
834
      {
 
835
         return ARES_ENOMEM;
 
836
      }
 
837
#endif
 
838
 
 
839
      /* If no specified servers, try a local named. */
 
840
      if (channel->nservers <= 0)
 
841
      {
 
842
         channel->servers = malloc(sizeof(struct server_state));
 
843
         if (!channel->servers)
 
844
            return ARES_ENOMEM;
 
845
         memset(channel->servers, '\0', sizeof(struct server_state));
 
846
 
 
847
#ifdef USE_IPV6
 
848
         channel->servers[0].family = AF_INET;
 
849
#endif
 
850
 
 
851
         channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
 
852
         channel->servers[0].default_localhost_server = 1;
 
853
         channel->nservers = 1;
 
854
 
 
855
         // if v6 is running...
 
856
         //   channel->servers[0].family = AF_INET6;
 
857
         //   channel->servers[0].addr6.s_addr = htonl6(IN6ADDR_LOOPBACK_INIT);
 
858
         // hard to decide if there is one server or two here
 
859
      }
 
860
   }
 
861
 
 
862
   if (channel->ndomains == -1)
 
863
   {
696
864
      /* Derive a default domain search list from the kernel hostname,
697
 
       * or set it to empty if the hostname isn't helpful.
698
 
       */
699
 
      if (gethostname(hostname, sizeof(hostname)) == -1
700
 
          || !strchr(hostname, '.'))
701
 
        {
702
 
          channel->domains = 0; // malloc(0);
703
 
          channel->ndomains = 0;
704
 
        }
 
865
      * or set it to empty if the hostname isn't helpful.
 
866
      */
 
867
      if (gethostname(hostname, sizeof(hostname)) == -1 || !strchr(hostname, '.'))
 
868
      {
 
869
         channel->domains = 0; // malloc(0);
 
870
         channel->ndomains = 0;
 
871
      }
705
872
      else
706
 
        {
707
 
          channel->domains = malloc(sizeof(char *));
708
 
          if (!channel->domains)
709
 
            return ARES_ENOMEM;
710
 
          channel->ndomains = 0;
711
 
          channel->domains[0] = strdup(strchr(hostname, '.') + 1);
712
 
          if (!channel->domains[0])
713
 
            return ARES_ENOMEM;
714
 
          channel->ndomains = 1;
715
 
        }
716
 
    }
 
873
      {
 
874
         channel->domains = malloc(sizeof(char *));
 
875
         if (!channel->domains)
 
876
            return ARES_ENOMEM;
 
877
         channel->ndomains = 0;
 
878
         channel->domains[0] = strdup(strchr(hostname, '.') + 1);
 
879
         if (!channel->domains[0])
 
880
            return ARES_ENOMEM;
 
881
         channel->ndomains = 1;
 
882
      }
 
883
   }
717
884
 
718
 
  if (channel->nsort == -1)
719
 
    {
 
885
   if (channel->nsort == -1)
 
886
   {
720
887
      channel->sortlist = NULL;
721
888
      channel->nsort = 0;
722
 
    }
 
889
   }
723
890
 
724
 
  if (!channel->lookups)
725
 
    {
 
891
   if (!channel->lookups)
 
892
   {
726
893
      channel->lookups = strdup("bf");
727
894
      if (!channel->lookups)
728
 
        return ARES_ENOMEM;
729
 
    }
 
895
         return ARES_ENOMEM;
 
896
   }
730
897
 
731
 
  return ARES_SUCCESS;
 
898
   return ARES_SUCCESS;
732
899
}
733
900
 
734
901
static int config_domain(ares_channel channel, char *str)
780
947
  /* Add a nameserver entry, if this is a valid address. */
781
948
 
782
949
  if (inet_pton4(str, (u_char *) & addr))   /* is it an IPv4 address? */
783
 
        family = AF_INET;
 
950
    family = AF_INET;
784
951
  else
785
952
  { 
786
 
        if (inet_pton6(str, (u_char *) & addr6))  /* how about an IPv6 address? */
787
 
          family = AF_INET6;
788
 
        else    
789
 
          return ARES_SUCCESS;  /* nope, it was garbage, return early */
 
953
    if (inet_pton6(str, (u_char *) & addr6))  /* how about an IPv6 address? */
 
954
      family = AF_INET6;
 
955
    else        
 
956
      return ARES_SUCCESS;      /* nope, it was garbage, return early */
790
957
  }
791
958
#else
792
959
  /* Add a nameserver entry, if this is a valid address. */
806
973
    newserv[*nservers].addr6 = addr6;  
807
974
  else  
808
975
#endif
809
 
        newserv[*nservers].addr = addr;
 
976
    newserv[*nservers].addr = addr;
810
977
 
811
978
  *servers = newserv;
812
979
  (*nservers)++;
997
1164
 */
998
1165
static int find_server(struct server_state *servers, int nservers, struct in_addr addr)
999
1166
{
1000
 
  int i = 0;
1001
 
 
1002
 
  if (nservers == 0)
1003
 
     return -1;
1004
 
 
1005
 
  for (; i < nservers; i++)
1006
 
    {
 
1167
   int i = 0;
 
1168
 
 
1169
   if (nservers == 0)
 
1170
   {
 
1171
      return -1;
 
1172
   }
 
1173
 
 
1174
   for (; i < nservers; i++)
 
1175
   {
1007
1176
      if (servers[i].addr.s_addr == addr.s_addr)
 
1177
      {
1008
1178
         break;
1009
 
    }
1010
 
  return (i < nservers ? i : -1);
 
1179
      }
 
1180
   }
 
1181
   return (i < nservers ? i : -1);
1011
1182
}
1012
1183
 
 
1184
#ifdef USE_IPV6
1013
1185
/*
1014
 
 * V4. Get the physical address of the first NIC whose list of DNS servers contain 'addr'.
1015
 
 * return: ARES_SUCCESS, etc.
 
1186
 * Finds a V6 addr in list of servers.
 
1187
 * return:
 
1188
 *  index i of servers whose servers[i].addr6 == addr
 
1189
 *  else -1, failed to find
1016
1190
 */
1017
 
static int get_physical_address(char *physicalAddr, int physicalAddrBufSz, int* physAddrLen, struct in_addr addr)
 
1191
static int find_server6(struct server_state *servers, int nservers, struct in6_addr addr)
1018
1192
{
1019
 
#ifdef WIN32
1020
 
  DWORD (WINAPI * GetAdaptersAddressesProc)(ULONG, DWORD, VOID *, IP_ADAPTER_ADDRESSES *, ULONG *);
1021
 
  HANDLE hLib = 0;
1022
 
  DWORD dwRet = ERROR_BUFFER_OVERFLOW;
1023
 
  DWORD dwSize = 0;
1024
 
  IP_ADAPTER_ADDRESSES *pAdapterAddresses = 0;
1025
 
  int rc = ARES_ENOTFOUND;
1026
 
 
1027
 
  memset(physicalAddr, '\0', physicalAddrBufSz);
1028
 
  *physAddrLen = 0;
1029
 
 
1030
 
  hLib = LoadLibrary(TEXT("iphlpapi.dll"));
1031
 
  if (!hLib)
1032
 
    return ARES_ENOTIMP;
1033
 
 
1034
 
  (void*)GetAdaptersAddressesProc = GetProcAddress(hLib, TEXT("GetAdaptersAddresses"));
1035
 
  if(!GetAdaptersAddressesProc)
1036
 
  {
1037
 
    rc = ARES_ENOTIMP;
1038
 
    goto cleanup;
1039
 
  }
1040
 
 
1041
 
  // Getting buffer size, expects overflow error
1042
 
  dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, NULL, &dwSize);
1043
 
  assert(dwRet == ERROR_BUFFER_OVERFLOW);
1044
 
  if (dwRet == ERROR_BUFFER_OVERFLOW)
1045
 
  {
1046
 
    pAdapterAddresses = (IP_ADAPTER_ADDRESSES *) LocalAlloc(LMEM_ZEROINIT, dwSize);
1047
 
    if (! pAdapterAddresses)
1048
 
    {
1049
 
      rc = ARES_ENOMEM;
1050
 
      goto cleanup;
1051
 
    }
1052
 
  }
1053
 
  else
1054
 
  {
1055
 
    //printf("ARES: couldn't get adapters addresses, dwRet=0x%x\n", dwRet);
1056
 
    rc = ARES_ENODATA;
1057
 
    goto cleanup;
1058
 
  }
1059
 
 
1060
 
  dwRet = (*GetAdaptersAddressesProc)(AF_UNSPEC, 0, NULL, pAdapterAddresses, &dwSize);
1061
 
  if (dwRet != ERROR_SUCCESS)
1062
 
  {
1063
 
    //printf("ARES: couldn't get adapters addresses (2), dwRet=0x%x\n", dwRet);
1064
 
    rc = ARES_ENODATA;
1065
 
    goto cleanup;
1066
 
  }
1067
 
 
1068
 
  {
1069
 
    IP_ADAPTER_ADDRESSES * AI = NULL;
1070
 
    for (AI = pAdapterAddresses; AI != NULL; AI = AI->Next)
1071
 
    {
1072
 
      PIP_ADAPTER_DNS_SERVER_ADDRESS dnsServers = AI->FirstDnsServerAddress;
1073
 
      // find 'addr' in adapter's list of dns servers.
1074
 
      for (; dnsServers; dnsServers = dnsServers->Next)
 
1193
   int i = 0;
 
1194
 
 
1195
   if (nservers == 0)
 
1196
   {
 
1197
      return -1;
 
1198
   }
 
1199
 
 
1200
   for (; i < nservers; i++)
 
1201
   {
 
1202
      if (memcmp(&servers[i].addr6, &addr, sizeof(addr)) == 0)
1075
1203
      {
1076
 
        if (! dnsServers->Address.lpSockaddr)
1077
 
          continue;
1078
 
 
1079
 
        if (dnsServers->Address.lpSockaddr->sa_family == AF_INET)
1080
 
        {
1081
 
          struct sockaddr_in sockAddr = *(struct sockaddr_in*)(dnsServers->Address.lpSockaddr);
1082
 
          if (memcmp(&addr, &sockAddr.sin_addr.s_addr, sizeof(struct in_addr)) == 0)
1083
 
          {
1084
 
            *physAddrLen = AI->PhysicalAddressLength;
1085
 
            if (*physAddrLen > physicalAddrBufSz)
1086
 
              *physAddrLen = physicalAddrBufSz;
1087
 
            memcpy(physicalAddr, &AI->PhysicalAddress[0], *physAddrLen);
1088
 
            rc = ARES_SUCCESS;
1089
 
            goto cleanup;
1090
 
          }
1091
 
        }
 
1204
         break;
1092
1205
      }
1093
 
    }
1094
 
  }
1095
 
  rc = ARES_ENOTFOUND;
1096
 
 
1097
 
cleanup:
1098
 
  if (hLib)
1099
 
    FreeLibrary(hLib);
1100
 
  if (pAdapterAddresses)
1101
 
    LocalFree(pAdapterAddresses);
1102
 
  return rc;
1103
 
#else // WIN32
1104
 
  return ARES_ENOTIMP;
1105
 
#endif // WIN32
 
1206
   }
 
1207
   return (i < nservers ? i : -1);
1106
1208
}
1107
 
 
 
1209
#endif
1108
1210
 
1109
1211
#define  NS_INT16SZ   2
1110
1212
#define  NS_INADDRSZ  4