MozillaFirefox/proxy-dev.patch

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;
+}