diff options
Diffstat (limited to 'pr/src/misc/prnetdb.c')
-rw-r--r-- | pr/src/misc/prnetdb.c | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c index 8a2a00c4..c21e1695 100644 --- a/pr/src/misc/prnetdb.c +++ b/pr/src/misc/prnetdb.c @@ -1,39 +1,7 @@ /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape Portable Runtime (NSPR). - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998-2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "primpl.h" @@ -95,7 +63,8 @@ PRLock *_pr_dnsLock = NULL; #if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \ || (defined(LINUX) && defined(_REENTRANT) \ - && !(defined(__GLIBC__) && __GLIBC__ >= 2)) + && !(defined(__GLIBC__) && __GLIBC__ >= 2) \ + && !defined(ANDROID)) #define _PR_HAVE_GETPROTO_R #define _PR_HAVE_GETPROTO_R_POINTER #endif @@ -1185,6 +1154,16 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( * any usable implementation. */ +#if defined(ANDROID) +/* Android's Bionic libc system includes prototypes for these in netdb.h, + * but doesn't actually include implementations. It uses the 5-arg form, + * so these functions end up not matching the prototype. So just rename + * them if not found. + */ +#define getprotobyname_r _pr_getprotobyname_r +#define getprotobynumber_r _pr_getprotobynumber_r +#endif + static struct protoent *getprotobyname_r(const char* name) { return getprotobyname(name); @@ -2019,7 +1998,7 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, #endif { PRADDRINFO *res, hints; - PRStatus rv; + int rv; /* * we assume a RFC 2553 compliant getaddrinfo. this may at some @@ -2028,7 +2007,32 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, */ memset(&hints, 0, sizeof(hints)); - hints.ai_flags = (flags & PR_AI_NOCANONNAME) ? 0: AI_CANONNAME; + if (!(flags & PR_AI_NOCANONNAME)) + hints.ai_flags |= AI_CANONNAME; +#ifdef AI_ADDRCONFIG + /* + * Propagate AI_ADDRCONFIG to the GETADDRINFO call if PR_AI_ADDRCONFIG + * is set. + * + * Need a workaround for loopback host addresses: + * The problem is that in glibc and Windows, AI_ADDRCONFIG applies the + * existence of an outgoing network interface to IP addresses of the + * loopback interface, due to a strict interpretation of the + * specification. For example, if a computer does not have any + * outgoing IPv6 network interface, but its loopback network interface + * supports IPv6, a getaddrinfo call on "localhost" with AI_ADDRCONFIG + * won't return the IPv6 loopback address "::1", because getaddrinfo + * thinks the computer cannot connect to any IPv6 destination, + * ignoring the remote vs. local/loopback distinction. + */ + if ((flags & PR_AI_ADDRCONFIG) && + strcmp(hostname, "localhost") != 0 && + strcmp(hostname, "localhost.localdomain") != 0 && + strcmp(hostname, "localhost6") != 0 && + strcmp(hostname, "localhost6.localdomain6") != 0) { + hints.ai_flags |= AI_ADDRCONFIG; + } +#endif hints.ai_family = (af == PR_AF_INET) ? AF_INET : AF_UNSPEC; /* @@ -2041,6 +2045,12 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, hints.ai_socktype = SOCK_STREAM; rv = GETADDRINFO(hostname, NULL, &hints, &res); +#ifdef AI_ADDRCONFIG + if (rv == EAI_BADFLAGS && (hints.ai_flags & AI_ADDRCONFIG)) { + hints.ai_flags &= ~AI_ADDRCONFIG; + rv = GETADDRINFO(hostname, NULL, &hints, &res); + } +#endif if (rv == 0) return (PRAddrInfo *) res; |