169 lines
4.7 KiB
Diff
169 lines
4.7 KiB
Diff
|
From: Robert O'Callahan <rocallahan@novell.com>
|
||
|
Subject: proxy.pac: host resolution error
|
||
|
References:
|
||
|
https://bugzilla.novell.com/show_bug.cgi?id=196506
|
||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=347307
|
||
|
|
||
|
Index: netwerk/base/src/nsProxyAutoConfig.js
|
||
|
================================================================================
|
||
|
--- netwerk/base/src/nsProxyAutoConfig.js
|
||
|
+++ netwerk/base/src/nsProxyAutoConfig.js
|
||
|
@@ -50,7 +50,7 @@
|
||
|
|
||
|
const nsISupports = Components.interfaces.nsISupports;
|
||
|
const nsIProxyAutoConfig = Components.interfaces.nsIProxyAutoConfig;
|
||
|
-const nsIDNSService = Components.interfaces.nsIDNSService;
|
||
|
+const nsPIDNSService = Components.interfaces.nsPIDNSService;
|
||
|
|
||
|
// implementor of nsIProxyAutoConfig
|
||
|
function nsProxyAutoConfig() {};
|
||
|
@@ -114,7 +114,7 @@
|
||
|
// wrapper for getting local IP address called by PAC file
|
||
|
function myIpAddress() {
|
||
|
try {
|
||
|
- return dns.resolve(dns.myHostName, 0).getNextAddrAsString();
|
||
|
+ return dns.getNetworkAddrAsString();
|
||
|
} catch (e) {
|
||
|
return '127.0.0.1';
|
||
|
}
|
||
|
@@ -176,7 +176,7 @@
|
||
|
}
|
||
|
|
||
|
var pac = new nsProxyAutoConfig() ;
|
||
|
-var dns = Components.classes[kDNS_CONTRACTID].getService(nsIDNSService);
|
||
|
+var dns = Components.classes[kDNS_CONTRACTID].getService(nsPIDNSService);
|
||
|
|
||
|
var pacUtils =
|
||
|
"function dnsDomainIs(host, domain) {\n" +
|
||
|
--- netwerk/dns/public/nsPIDNSService.idl
|
||
|
+++ netwerk/dns/public/nsPIDNSService.idl
|
||
|
@@ -58,4 +58,11 @@
|
||
|
* this method.
|
||
|
*/
|
||
|
void shutdown();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Returns the IP address of the machine that is most suitable for
|
||
|
+ * identifying the machine's network. Favour VPN addresses above
|
||
|
+ * wired/wireless addresses above 127.x.x.x addresses.
|
||
|
+ */
|
||
|
+ ACString getNetworkAddrAsString();
|
||
|
};
|
||
|
--- netwerk/dns/src/nsDNSService2.cpp
|
||
|
+++ netwerk/dns/src/nsDNSService2.cpp
|
||
|
@@ -56,6 +56,11 @@
|
||
|
#include "prio.h"
|
||
|
#include "plstr.h"
|
||
|
|
||
|
+#include <sys/types.h>
|
||
|
+#include <sys/socket.h>
|
||
|
+#include <ifaddrs.h>
|
||
|
+#include <net/if.h>
|
||
|
+
|
||
|
static const char kPrefDnsCacheEntries[] = "network.dnsCacheEntries";
|
||
|
static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration";
|
||
|
static const char kPrefEnableIDN[] = "network.enableIDN";
|
||
|
@@ -135,6 +140,18 @@
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
+static nsresult
|
||
|
+AddrToString(PRNetAddr* aAddr, nsACString& aResult)
|
||
|
+{
|
||
|
+ char buf[64];
|
||
|
+ if (PR_NetAddrToString(aAddr, buf, sizeof(buf)) == PR_SUCCESS) {
|
||
|
+ aResult.Assign(buf);
|
||
|
+ return NS_OK;
|
||
|
+ }
|
||
|
+ NS_ERROR("PR_NetAddrToString failed unexpectedly");
|
||
|
+ return NS_ERROR_FAILURE; // conversion failed for some reason
|
||
|
+}
|
||
|
+
|
||
|
NS_IMETHODIMP
|
||
|
nsDNSRecord::GetNextAddrAsString(nsACString &result)
|
||
|
{
|
||
|
@@ -142,13 +159,7 @@
|
||
|
nsresult rv = GetNextAddr(0, &addr);
|
||
|
if (NS_FAILED(rv)) return rv;
|
||
|
|
||
|
- char buf[64];
|
||
|
- if (PR_NetAddrToString(&addr, buf, sizeof(buf)) == PR_SUCCESS) {
|
||
|
- result.Assign(buf);
|
||
|
- return NS_OK;
|
||
|
- }
|
||
|
- NS_ERROR("PR_NetAddrToString failed unexpectedly");
|
||
|
- return NS_ERROR_FAILURE; // conversion failed for some reason
|
||
|
+ return AddrToString(&addr, result);
|
||
|
}
|
||
|
|
||
|
NS_IMETHODIMP
|
||
|
@@ -580,3 +591,68 @@
|
||
|
|
||
|
return af;
|
||
|
}
|
||
|
+
|
||
|
+static PRInt32
|
||
|
+GetScoreForInterface(struct ifaddrs* aInterface)
|
||
|
+{
|
||
|
+ // Interface must be up
|
||
|
+ if (!(aInterface->ifa_flags & IFF_UP))
|
||
|
+ return 0;
|
||
|
+ // Interface must be configured
|
||
|
+ if (!(aInterface->ifa_flags & IFF_RUNNING))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ // Only look at IP interfaces
|
||
|
+ sa_family_t type = aInterface->ifa_addr->sa_family;
|
||
|
+ if (type != AF_INET && type != AF_INET6)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ // Loopback interfaces get the lowest score
|
||
|
+ if (aInterface->ifa_flags & IFF_LOOPBACK)
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ if (strchr(aInterface->ifa_name, ':')) {
|
||
|
+ // guess that it's probably a VPN address
|
||
|
+ return 3;
|
||
|
+ }
|
||
|
+
|
||
|
+ // Regular interface
|
||
|
+ return 2;
|
||
|
+}
|
||
|
+
|
||
|
+nsresult
|
||
|
+SockaddrToString(struct sockaddr* aAddr, nsACString& aResult)
|
||
|
+{
|
||
|
+ PRNetAddr* addr = NS_REINTERPRET_CAST(PRNetAddr*, aAddr);
|
||
|
+ return AddrToString(addr, aResult);
|
||
|
+}
|
||
|
+
|
||
|
+NS_IMETHODIMP
|
||
|
+nsDNSService::GetNetworkAddrAsString(nsACString& aResult)
|
||
|
+{
|
||
|
+ aResult.AssignLiteral("127.0.0.1");
|
||
|
+
|
||
|
+ struct ifaddrs* addrs;
|
||
|
+ if (getifaddrs(&addrs) < 0)
|
||
|
+ return NS_OK;
|
||
|
+
|
||
|
+ struct ifaddrs* bestAddr = nsnull;
|
||
|
+ PRInt32 bestScore = 0;
|
||
|
+ struct ifaddrs* addr;
|
||
|
+ for (addr = addrs; addr; addr = addr->ifa_next) {
|
||
|
+ PRInt32 score = GetScoreForInterface(addr);
|
||
|
+ if (score > 0 && (!bestAddr || score > bestScore)) {
|
||
|
+ bestAddr = addr;
|
||
|
+ bestScore = score;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!bestAddr) {
|
||
|
+ freeifaddrs(addrs);
|
||
|
+ return NS_OK;
|
||
|
+ }
|
||
|
+
|
||
|
+ nsresult rv = SockaddrToString(bestAddr->ifa_addr, aResult);
|
||
|
+ freeifaddrs(addrs);
|
||
|
+ return rv;
|
||
|
+}
|