View | Details | Raw Unified | Return to bug 12398 | Differences between
and this patch

Collapse All | Expand All

(-)glibc-2.16.90-67cbf9a2.orig/sysdeps/posix/getaddrinfo.c (-60 / +54 lines)
Lines 829-842 Link Here
829
		}
829
		}
830
	    }
830
	    }
831
831
832
	  /* AI_ADDRCONFIG determines whether or not we should suppress any
833
	   * hostname lookups. If the local host has only IPv4 interfaces,
834
	   * then suppress lookups for IPv6 addresses, and vice versa; if
835
	   * the local host has only IPv6 interfaces, suppress any lookups
836
	   * for IPv4 addresses..
837
	   * 
838
	   * Link-local IPv6 addresses and loopback addresses of either
839
	   * family are ignored when determining whether or not the host has
840
	   * an interface of the given address family, cf. __check_pf().
841
	   *
842
	   * This logic is only applied for AF_UNSPEC. If the caller
843
	   * explicitly requested an address family, give him what he asked
844
	   * for.
845
	   *
846
	   * If we didn't find any interfaces of either address family,
847
	   * we ignore AI_ADDRCONFIG and return all available resutlts.  */
848
	  int suppress_af = 0;
849
	  if (req->ai_family == AF_UNSPEC && req->ai_flags & AI_ADDRCONFIG)
850
	    {
851
	      struct in6addrinfo *in6ai = NULL;
852
	      size_t in6ailen = 0;
853
	      bool seen_ipv4 = false;
854
	      bool seen_ipv6 = false;
855
	      __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
856
	      __free_in6ai (in6ai);
857
858
	      if(seen_ipv4 && !seen_ipv6)
859
		  suppress_af = AF_INET6;
860
	      else if(seen_ipv6 && !seen_ipv4)
861
		  suppress_af = AF_INET;
862
	    }
863
832
	  while (!no_more)
864
	  while (!no_more)
833
	    {
865
	    {
834
	      no_data = 0;
866
	      no_data = 0;
835
	      nss_gethostbyname4_r fct4 = NULL;
867
	      nss_gethostbyname4_r fct4 = NULL;
836
868
837
	      /* gethostbyname4_r sends out parallel A and AAAA queries and
869
	      /* gethostbyname4_r sends out parallel A and AAAA queries and
838
		 is thus only suitable for PF_UNSPEC.  */
870
		 is thus only suitable for PF_UNSPEC, and only if we're not
839
	      if (req->ai_family == PF_UNSPEC)
871
		 suppressing lookups for IPv4 or IPv6 addresses.  */
872
	      if (req->ai_family == PF_UNSPEC && !suppress_af)
840
		fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
873
		fct4 = __nss_lookup_function (nip, "gethostbyname4_r");
841
874
842
	      if (fct4 != NULL)
875
	      if (fct4 != NULL)
Lines 941-960 Link Here
941
974
942
		  if (fct != NULL)
975
		  if (fct != NULL)
943
		    {
976
		    {
944
		      if (req->ai_family == AF_INET6
977
		      if ((req->ai_family == AF_INET6
945
			  || req->ai_family == AF_UNSPEC)
978
			   || req->ai_family == AF_UNSPEC)
979
			  && suppress_af != AF_INET6)
946
			{
980
			{
947
			  gethosts (AF_INET6, struct in6_addr);
981
			  gethosts (AF_INET6, struct in6_addr);
948
			  no_inet6_data = no_data;
982
			  no_inet6_data = no_data;
949
			  inet6_status = status;
983
			  inet6_status = status;
950
			}
984
			}
951
		      if (req->ai_family == AF_INET
985
		      if ((req->ai_family == AF_INET
952
			  || req->ai_family == AF_UNSPEC
986
			   || req->ai_family == AF_UNSPEC
953
			  || (req->ai_family == AF_INET6
987
			   || (req->ai_family == AF_INET6
954
			      && (req->ai_flags & AI_V4MAPPED)
988
			       && (req->ai_flags & AI_V4MAPPED)
955
			      /* Avoid generating the mapped addresses if we
989
			       /* Avoid generating the mapped addresses if we
956
				 know we are not going to need them.  */
990
				  know we are not going to need them.  */
957
			      && ((req->ai_flags & AI_ALL) || !got_ipv6)))
991
			       && ((req->ai_flags & AI_ALL) || !got_ipv6)))
992
			  && suppress_af != AF_INET)
958
			{
993
			{
959
			  gethosts (AF_INET, struct in_addr);
994
			  gethosts (AF_INET, struct in_addr);
960
995
Lines 2373-2379 Link Here
2373
  int nresults = 0;
2408
  int nresults = 0;
2374
  struct addrinfo *p = NULL;
2409
  struct addrinfo *p = NULL;
2375
  struct gaih_service gaih_service, *pservice;
2410
  struct gaih_service gaih_service, *pservice;
2376
  struct addrinfo local_hints;
2377
2411
2378
  if (name != NULL && name[0] == '*' && name[1] == 0)
2412
  if (name != NULL && name[0] == '*' && name[1] == 0)
2379
    name = NULL;
2413
    name = NULL;
Lines 2399-2440 Link Here
2399
  if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2433
  if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
2400
    return EAI_BADFLAGS;
2434
    return EAI_BADFLAGS;
2401
2435
2402
  struct in6addrinfo *in6ai = NULL;
2403
  size_t in6ailen = 0;
2404
  bool seen_ipv4 = false;
2405
  bool seen_ipv6 = false;
2406
  bool check_pf_called = false;
2407
2408
  if (hints->ai_flags & AI_ADDRCONFIG)
2409
    {
2410
      /* We might need information about what interfaces are available.
2411
	 Also determine whether we have IPv4 or IPv6 interfaces or both.  We
2412
	 cannot cache the results since new interfaces could be added at
2413
	 any time.  */
2414
      __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2415
      check_pf_called = true;
2416
2417
      /* Now make a decision on what we return, if anything.  */
2418
      if (hints->ai_family == PF_UNSPEC && (seen_ipv4 || seen_ipv6))
2419
	{
2420
	  /* If we haven't seen both IPv4 and IPv6 interfaces we can
2421
	     narrow down the search.  */
2422
	  if ((! seen_ipv4 || ! seen_ipv6) && (seen_ipv4 || seen_ipv6))
2423
	    {
2424
	      local_hints = *hints;
2425
	      local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
2426
	      hints = &local_hints;
2427
	    }
2428
	}
2429
      else if ((hints->ai_family == PF_INET && ! seen_ipv4)
2430
	       || (hints->ai_family == PF_INET6 && ! seen_ipv6))
2431
	{
2432
	  /* We cannot possibly return a valid answer.  */
2433
	  __free_in6ai (in6ai);
2434
	  return EAI_NONAME;
2435
	}
2436
    }
2437
2438
  if (service && service[0])
2436
  if (service && service[0])
2439
    {
2437
    {
2440
      char *c;
2438
      char *c;
Lines 2443-2452 Link Here
2443
      if (*c != '\0')
2441
      if (*c != '\0')
2444
	{
2442
	{
2445
	  if (hints->ai_flags & AI_NUMERICSERV)
2443
	  if (hints->ai_flags & AI_NUMERICSERV)
2446
	    {
2447
	      __free_in6ai (in6ai);
2448
	      return EAI_NONAME;
2444
	      return EAI_NONAME;
2449
	    }
2450
2445
2451
	  gaih_service.num = -1;
2446
	  gaih_service.num = -1;
2452
	}
2447
	}
Lines 2466-2472 Link Here
2466
      if (last_i != 0)
2461
      if (last_i != 0)
2467
	{
2462
	{
2468
	  freeaddrinfo (p);
2463
	  freeaddrinfo (p);
2469
	  __free_in6ai (in6ai);
2470
2464
2471
	  return -(last_i & GAIH_EAI);
2465
	  return -(last_i & GAIH_EAI);
2472
	}
2466
	}
Lines 2477-2486 Link Here
2477
	}
2471
	}
2478
    }
2472
    }
2479
  else
2473
  else
2480
    {
2481
      __free_in6ai (in6ai);
2482
      return EAI_FAMILY;
2474
      return EAI_FAMILY;
2483
    }
2484
2475
2485
  if (naddrs > 1)
2476
  if (naddrs > 1)
2486
    {
2477
    {
Lines 2495-2503 Link Here
2495
      struct addrinfo *last = NULL;
2486
      struct addrinfo *last = NULL;
2496
      char *canonname = NULL;
2487
      char *canonname = NULL;
2497
2488
2498
      /* Now we definitely need the interface information.  */
2489
      /* Now we need the interface information.  */
2499
      if (! check_pf_called)
2490
      struct in6addrinfo *in6ai = NULL;
2500
	__check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2491
      size_t in6ailen = 0;
2492
      bool seen_ipv4 = false;
2493
      bool seen_ipv6 = false;
2494
      __check_pf (&seen_ipv4, &seen_ipv6, &in6ai, &in6ailen);
2501
2495
2502
      /* If we have information about deprecated and temporary addresses
2496
      /* If we have information about deprecated and temporary addresses
2503
	 sort the array now.  */
2497
	 sort the array now.  */
Lines 2664-2672 Link Here
2664
2658
2665
      /* Fill in the canonical name into the new first entry.  */
2659
      /* Fill in the canonical name into the new first entry.  */
2666
      p->ai_canonname = canonname;
2660
      p->ai_canonname = canonname;
2667
    }
2668
2661
2669
  __free_in6ai (in6ai);
2662
      __free_in6ai (in6ai);
2663
    }
2670
2664
2671
  if (p)
2665
  if (p)
2672
    {
2666
    {

Return to bug 12398