mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 14:55:47 +00:00
Bug 1700309 - Retry DNS query when RESOLVE_IP_HINT is set r=necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D109819
This commit is contained in:
parent
df6401195e
commit
abe7361f8b
@ -1229,11 +1229,21 @@ nsresult DnsAndConnectSocket::TransportSetup::ResolveHost(
|
||||
nullptr, NS_NET_STATUS_RESOLVING_HOST, 0);
|
||||
}
|
||||
|
||||
return dns->AsyncResolveNative(
|
||||
nsresult rv = dns->AsyncResolveNative(
|
||||
mHost, nsIDNSService::RESOLVE_TYPE_DEFAULT, mDnsFlags, nullptr,
|
||||
dnsAndSock, gSocketTransportService,
|
||||
dnsAndSock->mEnt->mConnInfo->GetOriginAttributes(),
|
||||
getter_AddRefs(mDNSRequest));
|
||||
if (NS_FAILED(rv) && (mDnsFlags & nsIDNSService::RESOLVE_IP_HINT)) {
|
||||
mDnsFlags &= ~nsIDNSService::RESOLVE_IP_HINT;
|
||||
return dns->AsyncResolveNative(
|
||||
mHost, nsIDNSService::RESOLVE_TYPE_DEFAULT, mDnsFlags, nullptr,
|
||||
dnsAndSock, gSocketTransportService,
|
||||
dnsAndSock->mEnt->mConnInfo->GetOriginAttributes(),
|
||||
getter_AddRefs(mDNSRequest));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult DnsAndConnectSocket::TransportSetup::OnLookupComplete(
|
||||
|
@ -9,6 +9,7 @@ ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
let prefs;
|
||||
let h2Port;
|
||||
let listen;
|
||||
let trrServer;
|
||||
|
||||
const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
|
||||
Ci.nsIDNSService
|
||||
@ -63,7 +64,7 @@ function setup() {
|
||||
}
|
||||
|
||||
setup();
|
||||
registerCleanupFunction(() => {
|
||||
registerCleanupFunction(async () => {
|
||||
prefs.clearUserPref("network.trr.mode");
|
||||
prefs.clearUserPref("network.http.spdy.enabled");
|
||||
prefs.clearUserPref("network.http.spdy.enabled.http2");
|
||||
@ -80,6 +81,8 @@ registerCleanupFunction(() => {
|
||||
prefs.clearUserPref("network.dns.upgrade_with_https_rr");
|
||||
prefs.clearUserPref("network.dns.use_https_rr_as_altsvc");
|
||||
prefs.clearUserPref("network.dns.native-is-localhost");
|
||||
prefs.clearUserPref("network.dns.disablePrefetch");
|
||||
await trrServer.stop();
|
||||
});
|
||||
|
||||
class DNSListener {
|
||||
@ -103,7 +106,7 @@ DNSListener.prototype.QueryInterface = ChromeUtils.generateQI([
|
||||
|
||||
// Test if IP hint addresses can be accessed as regular A/AAAA records.
|
||||
add_task(async function testStoreIPHint() {
|
||||
let trrServer = new TRRServer();
|
||||
trrServer = new TRRServer();
|
||||
registerCleanupFunction(async () => {
|
||||
await trrServer.stop();
|
||||
});
|
||||
@ -230,6 +233,8 @@ add_task(async function testStoreIPHint() {
|
||||
Ci.nsIDNSService.RESOLVE_IP_HINT | Ci.nsIDNSService.RESOLVE_DISABLE_IPV6,
|
||||
["1.2.3.4", "5.6.7.8"]
|
||||
);
|
||||
|
||||
await trrServer.stop();
|
||||
});
|
||||
|
||||
function makeChan(url) {
|
||||
@ -241,14 +246,14 @@ function makeChan(url) {
|
||||
return chan;
|
||||
}
|
||||
|
||||
function channelOpenPromise(chan) {
|
||||
function channelOpenPromise(chan, flags) {
|
||||
return new Promise(resolve => {
|
||||
function finish(req, buffer) {
|
||||
resolve([req, buffer]);
|
||||
}
|
||||
let internal = chan.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
internal.setWaitForHTTPSSVCRecord();
|
||||
chan.asyncOpen(new ChannelListener(finish, null, CL_ALLOW_UNKNOWN_CL));
|
||||
chan.asyncOpen(new ChannelListener(finish, null, flags));
|
||||
});
|
||||
}
|
||||
|
||||
@ -286,7 +291,7 @@ add_task(async function testConnectionWithIPHint() {
|
||||
);
|
||||
|
||||
// The connection should be succeeded since the IP hint is 127.0.0.1.
|
||||
let chan = makeChan(`http://test.iphint.com:8080/`);
|
||||
let chan = makeChan(`http://test.iphint.com:8080/server-timing`);
|
||||
// Note that the partitionKey stored in DNS cache would be
|
||||
// "%28https%2Ciphint.com%29". The http request to test.iphint.com will be
|
||||
// upgraded to https and the ip hint address will be used by the https
|
||||
@ -298,4 +303,111 @@ add_task(async function testConnectionWithIPHint() {
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
false
|
||||
);
|
||||
|
||||
await trrServer.stop();
|
||||
});
|
||||
|
||||
// Test the case that we failed to use IP Hint address because DNS cache
|
||||
// is bypassed.
|
||||
add_task(async function testIPHintWithFreshDNS() {
|
||||
trrServer = new TRRServer();
|
||||
await trrServer.start();
|
||||
Services.prefs.setIntPref("network.trr.mode", 3);
|
||||
Services.prefs.setCharPref(
|
||||
"network.trr.uri",
|
||||
`https://foo.example.com:${trrServer.port}/dns-query`
|
||||
);
|
||||
// To make sure NS_HTTP_REFRESH_DNS not be cleared.
|
||||
Services.prefs.setBoolPref("network.dns.disablePrefetch", true);
|
||||
|
||||
await trrServer.registerDoHAnswers("test.iphint.org", "HTTPS", {
|
||||
answers: [
|
||||
{
|
||||
name: "test.iphint.org",
|
||||
ttl: 55,
|
||||
type: "HTTPS",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 0,
|
||||
name: "svc.iphint.net",
|
||||
values: [],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await trrServer.registerDoHAnswers("svc.iphint.net", "HTTPS", {
|
||||
answers: [
|
||||
{
|
||||
name: "svc.iphint.net",
|
||||
ttl: 55,
|
||||
type: "HTTPS",
|
||||
flush: false,
|
||||
data: {
|
||||
priority: 1,
|
||||
name: "svc.iphint.net",
|
||||
values: [
|
||||
{ key: "alpn", value: "h2" },
|
||||
{ key: "port", value: h2Port },
|
||||
{ key: "ipv4hint", value: "127.0.0.1" },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let listener = new DNSListener();
|
||||
let request = dns.asyncResolve(
|
||||
"test.iphint.org",
|
||||
dns.RESOLVE_TYPE_HTTPSSVC,
|
||||
0,
|
||||
null, // resolverInfo
|
||||
listener,
|
||||
mainThread,
|
||||
defaultOriginAttributes
|
||||
);
|
||||
|
||||
let [inRequest, inRecord, inStatus] = await listener;
|
||||
Assert.equal(inRequest, request, "correct request was used");
|
||||
Assert.equal(inStatus, Cr.NS_OK, "status OK");
|
||||
let answer = inRecord.QueryInterface(Ci.nsIDNSHTTPSSVCRecord).records;
|
||||
Assert.equal(answer[0].priority, 1);
|
||||
Assert.equal(answer[0].name, "svc.iphint.net");
|
||||
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
true
|
||||
);
|
||||
|
||||
let chan = makeChan(`https://test.iphint.org/server-timing`);
|
||||
chan.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
let [req] = await channelOpenPromise(
|
||||
chan,
|
||||
CL_EXPECT_FAILURE | CL_ALLOW_UNKNOWN_CL
|
||||
);
|
||||
// Failed because there no A record for "svc.iphint.net".
|
||||
Assert.equal(req.status, Cr.NS_ERROR_UNKNOWN_HOST);
|
||||
|
||||
await trrServer.registerDoHAnswers("svc.iphint.net", "A", {
|
||||
answers: [
|
||||
{
|
||||
name: "svc.iphint.net",
|
||||
ttl: 55,
|
||||
type: "A",
|
||||
flush: false,
|
||||
data: "127.0.0.1",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
chan = makeChan(`https://test.iphint.org/server-timing`);
|
||||
chan.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
[req] = await channelOpenPromise(chan);
|
||||
Assert.equal(req.protocolVersion, "h2");
|
||||
let internal = req.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
Assert.equal(internal.remotePort, h2Port);
|
||||
|
||||
certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
|
||||
false
|
||||
);
|
||||
await trrServer.stop();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user