summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKai Engert <kaie@kuix.de>2022-05-13 20:12:20 +0200
committerKai Engert <kaie@kuix.de>2022-05-13 20:12:20 +0200
commit30efd57ebd474a8c3e53c732d1443a3ac6a160f9 (patch)
tree29c2db823e72332f638483d4ea799bd00b2131de
parentf7112dfe8414acc963e4a2a75a7c8e4c894781e9 (diff)
downloadnspr-hg-30efd57ebd474a8c3e53c732d1443a3ac6a160f9.tar.gz
Bug 1769293 - Add API PR_GetPrefLoopbackAddrInfo. r=rrelyea
Differential Revision: https://phabricator.services.mozilla.com/D146333
-rw-r--r--pr/include/prnetdb.h3
-rw-r--r--pr/src/misc/prnetdb.c67
-rw-r--r--pr/src/nspr.def4
3 files changed, 74 insertions, 0 deletions
diff --git a/pr/include/prnetdb.h b/pr/include/prnetdb.h
index 8506d21c..023a46e5 100644
--- a/pr/include/prnetdb.h
+++ b/pr/include/prnetdb.h
@@ -428,6 +428,9 @@ NSPR_API(void) PR_FreeAddrInfo(PRAddrInfo *addrInfo);
NSPR_API(void *) PR_EnumerateAddrInfo(
void *enumPtr, const PRAddrInfo *addrInfo, PRUint16 port, PRNetAddr *result);
+NSPR_API(PRStatus) PR_GetPrefLoopbackAddrInfo(PRNetAddr *result,
+ PRUint16 port);
+
/***********************************************************************
** FUNCTION:
** DESCRIPTION: PR_GetCanonNameFromAddrInfo()
diff --git a/pr/src/misc/prnetdb.c b/pr/src/misc/prnetdb.c
index baf49d81..7decd967 100644
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -2178,6 +2178,73 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname,
#endif
}
+PR_IMPLEMENT(PRStatus)
+PR_GetPrefLoopbackAddrInfo(PRNetAddr *result,
+ PRUint16 port)
+{
+ char tmpBuf[ 40 ];
+ const int tmpBufSize = sizeof( tmpBuf );
+
+ if (!result) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return PR_FAILURE;
+ }
+
+ if (!_pr_initialized) _PR_ImplicitInitialization();
+
+ PR_snprintf(tmpBuf, tmpBufSize, "%u", port );
+
+#if !defined(_PR_HAVE_GETADDRINFO) || !defined(AI_PASSIVE)
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return PR_FAILURE;
+#else
+
+ PRADDRINFO *res, hints;
+ PRStatus rv;
+
+ memset(&hints, 0, sizeof(hints));
+
+ rv = GETADDRINFO(NULL, tmpBuf, &hints, &res);
+ if (rv == 0) {
+ PRBool result_still_empty = PR_TRUE;
+ PRADDRINFO *ai = res;
+ do {
+ PRNetAddr aNetAddr;
+
+ while (ai && ai->ai_addrlen > sizeof(PRNetAddr))
+ ai = ai->ai_next;
+
+ if (ai) {
+ /* copy sockaddr to PRNetAddr */
+ memcpy(&aNetAddr, ai->ai_addr, ai->ai_addrlen);
+ aNetAddr.raw.family = ai->ai_addr->sa_family;
+#ifdef _PR_INET6
+ if (AF_INET6 == aNetAddr.raw.family)
+ aNetAddr.raw.family = PR_AF_INET6;
+#endif
+ if (ai->ai_addrlen < sizeof(PRNetAddr))
+ memset(((char*)result)+ai->ai_addrlen, 0,
+ sizeof(PRNetAddr) - ai->ai_addrlen);
+ }
+
+ /* If we obtain more than one result, prefer IPv6. */
+ if (result_still_empty || aNetAddr.raw.family == PR_AF_INET6) {
+ memcpy(result, &aNetAddr, sizeof(PRNetAddr));
+ }
+ result_still_empty = PR_FALSE;
+ ai = ai->ai_next;
+ }
+ while (ai);
+
+ FREEADDRINFO(res);
+ return PR_SUCCESS;
+ }
+
+ PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv);
+ return PR_FAILURE;
+#endif
+}
+
PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai)
{
#if defined(_PR_HAVE_GETADDRINFO)
diff --git a/pr/src/nspr.def b/pr/src/nspr.def
index 726979ba..49a437b1 100644
--- a/pr/src/nspr.def
+++ b/pr/src/nspr.def
@@ -462,3 +462,7 @@ EXPORTS ;-
PR_DuplicateEnvironment;
PR_GetEnvSecure;
;+} NSPR_4.10.3;
+;+NSPR_4.34 {
+;+ global:
+ PR_GetPrefLoopbackAddrInfo;
+;+} NSPR_4.12;