genericopenlibs/openenvcore/libc/src/net/getaddrinfo.c
changeset 63 a117ad66e027
parent 0 e4d67989cc36
child 71 28ccaba883f4
equal deleted inserted replaced
59:09fa7c3c5079 63:a117ad66e027
  1115 		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr))
  1115 		if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr))
  1116 			return(2); /* link-local scope */
  1116 			return(2); /* link-local scope */
  1117 		if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr))
  1117 		if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr))
  1118 			return(5); /* site-local scope */
  1118 			return(5); /* site-local scope */
  1119 		return(14);	/* global scope */
  1119 		return(14);	/* global scope */
  1120 		break;
  1120 
  1121 #endif
  1121 #endif
  1122 	case AF_INET:
  1122 	case AF_INET:
  1123 		/*
  1123 		/*
  1124 		 * IPv4 pseudo scoping according to RFC 3484.
  1124 		 * IPv4 pseudo scoping according to RFC 3484.
  1125 		 */
  1125 		 */
  1137 			return(14);	/* XXX: It should be 5 unless NAT */
  1137 			return(14);	/* XXX: It should be 5 unless NAT */
  1138 		/* Loopback addresses have link-local scope. */
  1138 		/* Loopback addresses have link-local scope. */
  1139 		if (((u_char *)&sa4->sin_addr)[0] == 127)
  1139 		if (((u_char *)&sa4->sin_addr)[0] == 127)
  1140 			return(2);
  1140 			return(2);
  1141 		return(14);
  1141 		return(14);
  1142 		break;
       
  1143 	default:
  1142 	default:
  1144 		errno = EAFNOSUPPORT; /* is this a good error? */
  1143 		errno = EAFNOSUPPORT; /* is this a good error? */
  1145 		return(-1);
  1144 		return(-1);
  1146 	}
  1145 	}
  1147 }
  1146 }
  1680 	else
  1679 	else
  1681 		return -1;
  1680 		return -1;
  1682 }
  1681 }
  1683 #endif
  1682 #endif
  1684 
  1683 
       
  1684 #ifdef __SYMBIAN32__
       
  1685 static long int
       
  1686 explore_hostname(pai, hostname, servname, res, hints)
       
  1687     struct addrinfo *pai;
       
  1688     const char *hostname;
       
  1689     const char *servname;
       
  1690     struct addrinfo **res;
       
  1691     const struct addrinfo *hints;
       
  1692     {
       
  1693     const struct afd *afd;
       
  1694     struct addrinfo *cur;
       
  1695     struct addrinfo sentinel;
       
  1696     int error;
       
  1697     int family_flag=0;
       
  1698     *res = NULL;
       
  1699 
       
  1700     sentinel.ai_next = NULL;
       
  1701     cur = &sentinel;
       
  1702 
       
  1703     /*
       
  1704      * if the servname does not match socktype/protocol, ignore it.
       
  1705      */
       
  1706 
       
  1707     if (get_portmatch(pai, servname) != 0)
       
  1708     return 0;
       
  1709     if (pai->ai_family == PF_UNSPEC)
       
  1710         {
       
  1711 #ifdef PF_INET6
       
  1712 #ifdef __SYMBIAN32__        
       
  1713         // XXX: Fix this
       
  1714         pai->ai_family = PF_INET;
       
  1715 #else           
       
  1716         pai->ai_family = PF_INET6;
       
  1717 #endif // __SYMBIAN32__ 
       
  1718 #else
       
  1719         pai->ai_family = PF_INET;
       
  1720 #endif
       
  1721         family_flag=1;
       
  1722         }
       
  1723 
       
  1724     afd = find_afd(pai->ai_family);
       
  1725     if (afd == NULL && family_flag)
       
  1726         {
       
  1727         if (pai->ai_family == PF_INET6)
       
  1728             {
       
  1729             pai->ai_family = PF_INET;
       
  1730             }
       
  1731         else
       
  1732             {
       
  1733             pai->ai_family = PF_INET6;
       
  1734             }
       
  1735         afd = find_afd(pai->ai_family);
       
  1736         }
       
  1737 
       
  1738     if (afd == NULL)
       
  1739         {
       
  1740         return 0;
       
  1741         }
       
  1742 
       
  1743     if (pai->ai_family == PF_UNSPEC || pai->ai_family == afd->a_af)
       
  1744         {
       
  1745         struct addrinfo *resNative;
       
  1746         struct addrinfo *currNative;
       
  1747         int haveV6asV4 = 0;
       
  1748         int haveV4asV6 = 0;
       
  1749         int haverealv4 = 0;
       
  1750         /* Get the list of addresses using the native api */
       
  1751         int ret = getaddrinfo_private(hostname, pai, &resNative);
       
  1752         if (ret != 0)
       
  1753             {
       
  1754             ERR(ret);
       
  1755             }
       
  1756 
       
  1757         /* copy the addresses to the local list */
       
  1758         currNative = resNative;
       
  1759         while (currNative)
       
  1760             {
       
  1761             if (currNative->ai_family == PF_INET && (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC))
       
  1762                 {
       
  1763                 if (currNative->ai_flags & AI_V4CONVERTED)
       
  1764                     {
       
  1765                     haveV6asV4 = 1;
       
  1766                     }
       
  1767                 else
       
  1768                     {
       
  1769                     struct sockaddr_in* sAddrTmp = (struct sockaddr_in*) (currNative->ai_addr);
       
  1770                     GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin_addr));
       
  1771                     cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family = PF_INET;
       
  1772                     GET_PORT(cur->ai_next, servname);
       
  1773 
       
  1774                     if (pai->ai_flags & AI_CANONNAME)
       
  1775                         {
       
  1776                         GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  1777                         }
       
  1778 
       
  1779                     cur = cur->ai_next;
       
  1780                     haverealv4 = 1;
       
  1781                     }
       
  1782                 }
       
  1783 
       
  1784             if (currNative->ai_family == PF_INET6 && (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC))
       
  1785                 {
       
  1786                 if (currNative->ai_flags & AI_V4MAPPED)
       
  1787                     {
       
  1788                     haveV4asV6 = 1;
       
  1789                     }
       
  1790                 else
       
  1791                     {
       
  1792                     struct sockaddr_in6* sAddrTmp = (struct sockaddr_in6*) (currNative->ai_addr);
       
  1793                     GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin6_addr));
       
  1794                     cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family = PF_INET6;
       
  1795                     GET_PORT(cur->ai_next, servname);
       
  1796 
       
  1797                     if (pai->ai_flags & AI_CANONNAME)
       
  1798                         {
       
  1799                         GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  1800                         }
       
  1801                     
       
  1802                     cur = cur->ai_next;
       
  1803                     }
       
  1804                 }
       
  1805 
       
  1806             currNative = currNative->ai_next;
       
  1807             }
       
  1808         
       
  1809         if (hints->ai_family == PF_INET6 && hints->ai_flags & AI_V4MAPPED && !sentinel.ai_next && haveV4asV6)
       
  1810             {
       
  1811             currNative = resNative;
       
  1812             while (currNative)
       
  1813                 {
       
  1814                 // check for addresses converted from v4 to v6
       
  1815                 if (currNative->ai_flags & AI_V4MAPPED)
       
  1816                     {
       
  1817                     struct sockaddr_in6* sAddrTmp = (struct sockaddr_in6*) (currNative->ai_addr);
       
  1818                     GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin6_addr));
       
  1819                     cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family = PF_INET6;
       
  1820                     GET_PORT(cur->ai_next, servname);
       
  1821                     currNative->ai_flags &= ~AI_V4MAPPED;
       
  1822     
       
  1823                     if (pai->ai_flags & AI_CANONNAME)
       
  1824                         {
       
  1825                         GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  1826                         }
       
  1827                     
       
  1828                     cur = cur->ai_next;
       
  1829                     }
       
  1830     
       
  1831                 currNative = currNative->ai_next;
       
  1832                 }
       
  1833             }
       
  1834         
       
  1835         if (haveV6asV4)
       
  1836             {
       
  1837             if ((hints->ai_family == PF_INET && !sentinel.ai_next) || (hints->ai_family == PF_UNSPEC && !haverealv4) || (hints->ai_flags & (AI_V4MAPPED|AI_ALL)))
       
  1838                 {
       
  1839                 currNative = resNative;
       
  1840                 while (currNative)
       
  1841                     {
       
  1842                     // check for addresses converted from v6 to v4
       
  1843                     if (currNative->ai_flags & AI_V4CONVERTED)
       
  1844                         {
       
  1845                         struct sockaddr_in* sAddrTmp = (struct sockaddr_in*) (currNative->ai_addr);
       
  1846                         GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin_addr));
       
  1847                         cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family = PF_INET;
       
  1848                         GET_PORT(cur->ai_next, servname);
       
  1849                         currNative->ai_flags &= ~AI_V4CONVERTED;
       
  1850 
       
  1851                         if (pai->ai_flags & AI_CANONNAME)
       
  1852                             {
       
  1853                             GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  1854                             }
       
  1855                         
       
  1856                         cur = cur->ai_next;
       
  1857                         }
       
  1858 
       
  1859                     currNative = currNative->ai_next;
       
  1860                     }
       
  1861                 }
       
  1862             }
       
  1863 
       
  1864         /* free the address list returned by native api */
       
  1865         freeaddrinfo_private(resNative);
       
  1866         }
       
  1867     else
       
  1868         {
       
  1869         ERR(EAI_FAMILY);
       
  1870         }
       
  1871 
       
  1872     *res = sentinel.ai_next;
       
  1873     return 0;
       
  1874 
       
  1875 free:
       
  1876 bad:
       
  1877     if (sentinel.ai_next)
       
  1878         {
       
  1879         freeaddrinfo(sentinel.ai_next);
       
  1880         }
       
  1881     return error;
       
  1882     }
       
  1883 
       
  1884 #endif//__SYMBIAN32__
       
  1885 
  1685 /*
  1886 /*
  1686  * FQDN hostname, DNS lookup
  1887  * FQDN hostname, DNS lookup
  1687  */
  1888  */
  1688 #ifndef __SYMBIAN32__
  1889 #ifndef __SYMBIAN32__
  1689 static int
  1890 static int
  1739 	if (result)
  1940 	if (result)
  1740 		freeaddrinfo(result);
  1941 		freeaddrinfo(result);
  1741 	return error;
  1942 	return error;
  1742 }
  1943 }
  1743 #endif
  1944 #endif
       
  1945 
       
  1946 #ifndef __SYMBIAN32__
  1744 #ifdef DEBUG
  1947 #ifdef DEBUG
  1745 static const char AskedForGot[] =
  1948 static const char AskedForGot[] =
  1746 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
  1949 	"gethostby*.getanswer: asked for \"%s\", got \"%s\"";
  1747 #endif
  1950 #endif
  1748 
  1951 
  1749 #ifndef __SYMBIAN32__
       
  1750 static struct addrinfo *
  1952 static struct addrinfo *
  1751 getanswer(answer, anslen, qname, qtype, pai)
  1953 getanswer(answer, anslen, qname, qtype, pai)
  1752 	const querybuf *answer;
  1954 	const querybuf *answer;
  1753 	int anslen;
  1955 	int anslen;
  1754 	const char *qname;
  1956 	const char *qname;
  2728 	}
  2930 	}
  2729 	return (res_queryN(longname, target));
  2931 	return (res_queryN(longname, target));
  2730 }
  2932 }
  2731 #endif /*__SYMBIAN32__*/
  2933 #endif /*__SYMBIAN32__*/
  2732 
  2934 
  2733 #ifdef __SYMBIAN32__
       
  2734 static long int
       
  2735 explore_hostname(pai, hostname, servname, res, hints)
       
  2736 	struct addrinfo *pai;
       
  2737 	const char *hostname;
       
  2738 	const char *servname;
       
  2739 	struct addrinfo **res;
       
  2740 	const struct addrinfo *hints;
       
  2741 {
       
  2742 	const struct afd *afd;
       
  2743 	struct addrinfo *cur;
       
  2744 	struct addrinfo sentinel;
       
  2745 	int error;
       
  2746     int family_flag=0;
       
  2747 	*res = NULL;
       
  2748 	
       
  2749 	sentinel.ai_next = NULL;
       
  2750 	cur = &sentinel;
       
  2751  
       
  2752 	/*
       
  2753 	 * if the servname does not match socktype/protocol, ignore it.
       
  2754 	 */
       
  2755  
       
  2756  	if (get_portmatch(pai, servname) != 0)
       
  2757 	 	return 0;
       
  2758         if (pai->ai_family == PF_UNSPEC) {
       
  2759 #ifdef PF_INET6
       
  2760 #ifdef __SYMBIAN32__		
       
  2761 // XXX: Fix this
       
  2762 			pai->ai_family = PF_INET;
       
  2763 #else			
       
  2764 			pai->ai_family = PF_INET6;
       
  2765 #endif // __SYMBIAN32__	
       
  2766 #else
       
  2767 			pai->ai_family = PF_INET;
       
  2768 #endif
       
  2769             family_flag=1;
       
  2770         }
       
  2771      
       
  2772 	afd = find_afd(pai->ai_family);
       
  2773     if( afd==NULL && family_flag )
       
  2774        	{
       
  2775        	if(pai->ai_family==PF_INET6)
       
  2776        		{
       
  2777        		pai->ai_family=PF_INET;
       
  2778        		}
       
  2779        	else
       
  2780        		{
       
  2781        		pai->ai_family=PF_INET6;
       
  2782        		}
       
  2783        	afd=find_afd(pai->ai_family);
       
  2784        	}
       
  2785 
       
  2786     if (afd == NULL)
       
  2787         {
       
  2788         return 0;
       
  2789         }
       
  2790        
       
  2791 	if ( pai->ai_family == PF_UNSPEC ||pai->ai_family == afd->a_af)
       
  2792 		{
       
  2793 		struct addrinfo *resNative;
       
  2794 		struct addrinfo *currNative;
       
  2795 		int haveV4Mapped = 0;
       
  2796 		/* Get the list of addresses using the native api */
       
  2797 		int ret = getaddrinfo_private(hostname, pai, &resNative);
       
  2798 		if(ret != 0)
       
  2799 			ERR(ret);
       
  2800 		
       
  2801 		/* copy the addresses to the local list */
       
  2802 		currNative = resNative;
       
  2803 	      while(currNative)
       
  2804 	            {
       
  2805 	            if(currNative->ai_family == PF_INET && (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC))
       
  2806 	                {
       
  2807 	                if(currNative->ai_flags & AI_V4MAPPED)
       
  2808 	                    {
       
  2809 	                    haveV4Mapped = 1;
       
  2810 	                    }
       
  2811 	                else
       
  2812 	                    {
       
  2813 	                    struct sockaddr_in* sAddrTmp = (struct sockaddr_in*) (currNative->ai_addr);
       
  2814 	                    GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin_addr));
       
  2815 	                    cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family  = PF_INET;
       
  2816 	                    GET_PORT(cur->ai_next, servname);
       
  2817 	                    
       
  2818 	                    if((pai->ai_flags & AI_CANONNAME)) 
       
  2819 	                        GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  2820 	                    
       
  2821 	                    cur = cur->ai_next;
       
  2822 	                    }
       
  2823 	                }
       
  2824 	            
       
  2825 	            if(currNative->ai_family == PF_INET6 && (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC))
       
  2826 	                {
       
  2827 	                struct sockaddr_in6* sAddrTmp = (struct sockaddr_in6*) (currNative->ai_addr);
       
  2828 	                GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin6_addr));
       
  2829 	                cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family = PF_INET6;
       
  2830 	                GET_PORT(cur->ai_next, servname);
       
  2831 	                 
       
  2832 	                if((pai->ai_flags & AI_CANONNAME)) 
       
  2833 	                    GET_CANONNAME(cur->ai_next, currNative->ai_canonname);
       
  2834 	                
       
  2835 	                cur = cur->ai_next;
       
  2836 	                }
       
  2837 	            
       
  2838 	            currNative = currNative->ai_next;   
       
  2839 	            }
       
  2840 
       
  2841 	        if(hints->ai_family == PF_INET && !sentinel.ai_next && haveV4Mapped)
       
  2842 	            {
       
  2843 	            currNative = resNative;
       
  2844 	            while(currNative)
       
  2845 	                {
       
  2846 	                //This is the set of Mapped Addresses.
       
  2847 	                if(currNative->ai_flags & AI_V4MAPPED)
       
  2848 	                    {
       
  2849 	                    struct sockaddr_in* sAddrTmp = (struct sockaddr_in*) (currNative->ai_addr);
       
  2850 	                    currNative->ai_flags &= ~AI_V4MAPPED;
       
  2851 	                    GET_AI(cur->ai_next, afd, (char*)&(sAddrTmp->sin_addr));
       
  2852 	                    cur->ai_next->ai_addr->sa_family = cur->ai_next->ai_family  = PF_INET;
       
  2853 	                    GET_PORT(cur->ai_next, servname);
       
  2854 	                    
       
  2855 	                    if((pai->ai_flags & AI_CANONNAME)) 
       
  2856 	                        GET_CANONNAME(cur->ai_next, currNative->ai_canonname);      
       
  2857 	                    cur = cur->ai_next;
       
  2858 	                    }
       
  2859 	                
       
  2860 	                currNative = currNative->ai_next;   
       
  2861 	                }
       
  2862 	            }
       
  2863 		/* free the address list returned by native api */
       
  2864 		freeaddrinfo_private(resNative);
       
  2865 		}
       
  2866 	else
       
  2867 		ERR(EAI_FAMILY);
       
  2868 
       
  2869 	*res = sentinel.ai_next;
       
  2870 	return 0;
       
  2871 
       
  2872 free:
       
  2873 bad:
       
  2874 	if (sentinel.ai_next)
       
  2875 		freeaddrinfo(sentinel.ai_next);
       
  2876 	return error;
       
  2877 }
       
  2878 
       
  2879 #endif//__SYMBIAN32__