Backed out 4 changesets (bug 1660970, bug 1525854, bug 1663657, bug 1645108) for perma failures on test_trr_additional_section.js. CLOSED TREE

Backed out changeset ad6c2e8af09b (bug 1663657)
Backed out changeset 419e26e3f452 (bug 1525854)
Backed out changeset 55bf856faf33 (bug 1660970)
Backed out changeset c543a3a008fa (bug 1645108)
This commit is contained in:
Razvan Maries
2020-09-15 02:35:05 +03:00
parent 81a9188e26
commit 287a69b58e
29 changed files with 146 additions and 925 deletions

View File

@@ -380,14 +380,14 @@ bool nsHTTPSOnlyUtils::LoopbackOrLocalException(nsIURI* aURI) {
mozilla::net::NetAddr addr(&tempAddr); mozilla::net::NetAddr addr(&tempAddr);
// Loopback IPs are always exempt // Loopback IPs are always exempt
if (addr.IsLoopbackAddr()) { if (IsLoopBackAddress(&addr)) {
return true; return true;
} }
// Local IP exception can get disabled with a pref // Local IP exception can get disabled with a pref
bool upgradeLocal = bool upgradeLocal =
mozilla::StaticPrefs::dom_security_https_only_mode_upgrade_local(); mozilla::StaticPrefs::dom_security_https_only_mode_upgrade_local();
return (!upgradeLocal && addr.IsIPAddrLocal()); return (!upgradeLocal && IsIPAddrLocal(&addr));
} }
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////

View File

@@ -251,7 +251,7 @@ bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackHost(
// address, whereas for IPv4 127.0.0.1/8 are considered as potentially // address, whereas for IPv4 127.0.0.1/8 are considered as potentially
// trustworthy. We already handled "[::1]" above, so all that's remained to // trustworthy. We already handled "[::1]" above, so all that's remained to
// handle here are IPv4 loopback addresses. // handle here are IPv4 loopback addresses.
return addr.IsIPAddrV4() && addr.IsLoopbackAddr(); return IsIPAddrV4(&addr) && IsLoopBackAddress(&addr);
} }
bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) { bool nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(nsIURI* aURL) {

View File

@@ -498,7 +498,7 @@ static bool PACResolveToString(const nsCString& aHostName,
if (!PACResolve(aHostName, &netAddr, aTimeout)) return false; if (!PACResolve(aHostName, &netAddr, aTimeout)) return false;
char dottedDecimal[128]; char dottedDecimal[128];
if (!netAddr.ToStringBuffer(dottedDecimal, sizeof(dottedDecimal))) if (!NetAddrToString(&netAddr, dottedDecimal, sizeof(dottedDecimal)))
return false; return false;
aDottedDecimal.Assign(dottedDecimal); aDottedDecimal.Assign(dottedDecimal);

View File

@@ -33,7 +33,7 @@ interface nsINetAddr : nsISupports
/** /**
* @return Either the IP address (FAMILY_INET, FAMILY_INET6) or the path * @return Either the IP address (FAMILY_INET, FAMILY_INET6) or the path
* (FAMILY_LOCAL) in string form. IP addresses are in the format produced by * (FAMILY_LOCAL) in string form. IP addresses are in the format produced by
* mozilla::net::NetAddr::ToStringBuffer. * mozilla::net::NetAddrToString.
* *
* Note: Paths for FAMILY_LOCAL may have length limitations which are * Note: Paths for FAMILY_LOCAL may have length limitations which are
* implementation dependent and not documented as part of this interface. * implementation dependent and not documented as part of this interface.

View File

@@ -739,7 +739,7 @@ nsresult nsIOService::RecheckCaptivePortalIfLocalRedirect(nsIChannel* newChan) {
} }
NetAddr netAddr(&prAddr); NetAddr netAddr(&prAddr);
if (netAddr.IsIPAddrLocal()) { if (IsIPAddrLocal(&netAddr)) {
// Redirects to local IP addresses are probably captive portals // Redirects to local IP addresses are probably captive portals
RecheckCaptivePortal(); RecheckCaptivePortal();
} }
@@ -947,7 +947,7 @@ nsIOService::HostnameIsLocalIPAddress(nsIURI* aURI, bool* aResult) {
PRStatus result = PR_StringToNetAddr(host.get(), &addr); PRStatus result = PR_StringToNetAddr(host.get(), &addr);
if (result == PR_SUCCESS) { if (result == PR_SUCCESS) {
NetAddr netAddr(&addr); NetAddr netAddr(&addr);
if (netAddr.IsIPAddrLocal()) { if (IsIPAddrLocal(&netAddr)) {
*aResult = true; *aResult = true;
} }
} }
@@ -974,7 +974,7 @@ nsIOService::HostnameIsSharedIPAddress(nsIURI* aURI, bool* aResult) {
PRStatus result = PR_StringToNetAddr(host.get(), &addr); PRStatus result = PR_StringToNetAddr(host.get(), &addr);
if (result == PR_SUCCESS) { if (result == PR_SUCCESS) {
NetAddr netAddr(&addr); NetAddr netAddr(&addr);
if (netAddr.IsIPAddrShared()) { if (IsIPAddrShared(&netAddr)) {
*aResult = true; *aResult = true;
} }
} }

View File

@@ -37,12 +37,12 @@ NS_IMETHODIMP nsNetAddr::GetAddress(nsACString& aAddress) {
/* PR_NetAddrToString can handle INET and INET6, but not LOCAL. */ /* PR_NetAddrToString can handle INET and INET6, but not LOCAL. */
case AF_INET: case AF_INET:
aAddress.SetLength(kIPv4CStrBufSize); aAddress.SetLength(kIPv4CStrBufSize);
mAddr.ToStringBuffer(aAddress.BeginWriting(), kIPv4CStrBufSize); NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv4CStrBufSize);
aAddress.SetLength(strlen(aAddress.BeginReading())); aAddress.SetLength(strlen(aAddress.BeginReading()));
break; break;
case AF_INET6: case AF_INET6:
aAddress.SetLength(kIPv6CStrBufSize); aAddress.SetLength(kIPv6CStrBufSize);
mAddr.ToStringBuffer(aAddress.BeginWriting(), kIPv6CStrBufSize); NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv6CStrBufSize);
aAddress.SetLength(strlen(aAddress.BeginReading())); aAddress.SetLength(strlen(aAddress.BeginReading()));
break; break;
#if defined(XP_UNIX) #if defined(XP_UNIX)

View File

@@ -892,7 +892,7 @@ nsresult nsSocketTransport::InitWithConnectedSocket(PRFileDesc* fd,
NS_ASSERTION(!mFD.IsInitialized(), "already initialized"); NS_ASSERTION(!mFD.IsInitialized(), "already initialized");
char buf[kNetAddrMaxCStrBufSize]; char buf[kNetAddrMaxCStrBufSize];
addr->ToStringBuffer(buf, sizeof(buf)); NetAddrToString(addr, buf, sizeof(buf));
mHost.Assign(buf); mHost.Assign(buf);
uint16_t port; uint16_t port;
@@ -1310,8 +1310,8 @@ nsresult nsSocketTransport::InitiateSocket() {
#endif #endif
if (NS_SUCCEEDED(mCondition) && xpc::AreNonLocalConnectionsDisabled() && if (NS_SUCCEEDED(mCondition) && xpc::AreNonLocalConnectionsDisabled() &&
!(mNetAddr.IsIPAddrAny() || mNetAddr.IsIPAddrLocal() || !(IsIPAddrAny(&mNetAddr) || IsIPAddrLocal(&mNetAddr) ||
mNetAddr.IsIPAddrShared())) { IsIPAddrShared(&mNetAddr))) {
nsAutoCString ipaddr; nsAutoCString ipaddr;
RefPtr<nsNetAddr> netaddr = new nsNetAddr(&mNetAddr); RefPtr<nsNetAddr> netaddr = new nsNetAddr(&mNetAddr);
netaddr->GetAddress(ipaddr); netaddr->GetAddress(ipaddr);
@@ -1333,11 +1333,11 @@ nsresult nsSocketTransport::InitiateSocket() {
// Hosts/Proxy Hosts that are Local IP Literals should not be speculatively // Hosts/Proxy Hosts that are Local IP Literals should not be speculatively
// connected - Bug 853423. // connected - Bug 853423.
if (mConnectionFlags & nsISocketTransport::DISABLE_RFC1918 && if (mConnectionFlags & nsISocketTransport::DISABLE_RFC1918 &&
mNetAddr.IsIPAddrLocal()) { IsIPAddrLocal(&mNetAddr)) {
if (SOCKET_LOG_ENABLED()) { if (SOCKET_LOG_ENABLED()) {
nsAutoCString netAddrCString; nsAutoCString netAddrCString;
netAddrCString.SetLength(kIPv6CStrBufSize); netAddrCString.SetLength(kIPv6CStrBufSize);
if (!mNetAddr.ToStringBuffer(netAddrCString.BeginWriting(), if (!NetAddrToString(&mNetAddr, netAddrCString.BeginWriting(),
kIPv6CStrBufSize)) kIPv6CStrBufSize))
netAddrCString = "<IP-to-string failed>"_ns; netAddrCString = "<IP-to-string failed>"_ns;
SOCKET_LOG( SOCKET_LOG(
@@ -1522,7 +1522,7 @@ nsresult nsSocketTransport::InitiateSocket() {
if (SOCKET_LOG_ENABLED()) { if (SOCKET_LOG_ENABLED()) {
char buf[kNetAddrMaxCStrBufSize]; char buf[kNetAddrMaxCStrBufSize];
mNetAddr.ToStringBuffer(buf, sizeof(buf)); NetAddrToString(&mNetAddr, buf, sizeof(buf));
SOCKET_LOG((" trying address: %s\n", buf)); SOCKET_LOG((" trying address: %s\n", buf));
} }
@@ -2526,7 +2526,7 @@ void nsSocketTransport::IsLocal(bool* aIsLocal) {
} }
#endif #endif
*aIsLocal = mNetAddr.IsLoopbackAddr(); *aIsLocal = IsLoopBackAddress(&mNetAddr);
} }
} }

View File

@@ -70,7 +70,7 @@ static nsresult CheckIOStatus(const NetAddr* aAddr) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (gIOService->IsOffline() && !aAddr->IsLoopbackAddr()) { if (gIOService->IsOffline() && !IsLoopBackAddress(aAddr)) {
return NS_ERROR_OFFLINE; return NS_ERROR_OFFLINE;
} }
@@ -472,7 +472,7 @@ void nsUDPSocket::OnSocketDetached(PRFileDesc* fd) {
void nsUDPSocket::IsLocal(bool* aIsLocal) { void nsUDPSocket::IsLocal(bool* aIsLocal) {
// If bound to loopback, this UDP socket only accepts local connections. // If bound to loopback, this UDP socket only accepts local connections.
*aIsLocal = mAddr.IsLoopbackAddr(); *aIsLocal = IsLoopBackAddress(&mAddr);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -567,7 +567,7 @@ nsUDPSocket::InitWithAddress(const NetAddr* aAddr, nsIPrincipal* aPrincipal,
} }
uint16_t port; uint16_t port;
if (NS_FAILED(aAddr->GetPort(&port))) { if (NS_FAILED(net::GetPort(aAddr, &port))) {
NS_WARNING("invalid bind address"); NS_WARNING("invalid bind address");
goto fail; goto fail;
} }
@@ -684,7 +684,7 @@ NS_IMETHODIMP
nsUDPSocket::GetPort(int32_t* aResult) { nsUDPSocket::GetPort(int32_t* aResult) {
// no need to enter the lock here // no need to enter the lock here
uint16_t result; uint16_t result;
nsresult rv = mAddr.GetPort(&result); nsresult rv = net::GetPort(&mAddr, &result);
*aResult = static_cast<int32_t>(result); *aResult = static_cast<int32_t>(result);
return rv; return rv;
} }

View File

@@ -98,8 +98,7 @@ void NetAddrToPRNetAddr(const NetAddr* addr, PRNetAddr* prAddr) {
#endif #endif
} }
bool NetAddr::ToStringBuffer(char* buf, uint32_t bufSize) const { bool NetAddrToString(const NetAddr* addr, char* buf, uint32_t bufSize) {
const NetAddr* addr = this;
if (addr->raw.family == AF_INET) { if (addr->raw.family == AF_INET) {
if (bufSize < INET_ADDRSTRLEN) { if (bufSize < INET_ADDRSTRLEN) {
return false; return false;
@@ -139,8 +138,7 @@ bool NetAddr::ToStringBuffer(char* buf, uint32_t bufSize) const {
return false; return false;
} }
bool NetAddr::IsLoopbackAddr() const { bool IsLoopBackAddress(const NetAddr* addr) {
const NetAddr* addr = this;
if (addr->raw.family == AF_INET) { if (addr->raw.family == AF_INET) {
// Consider 127.0.0.1/8 as loopback // Consider 127.0.0.1/8 as loopback
uint32_t ipv4Addr = ntohl(addr->inet.ip); uint32_t ipv4Addr = ntohl(addr->inet.ip);
@@ -159,17 +157,17 @@ bool NetAddr::IsLoopbackAddr() const {
return false; return false;
} }
bool NetAddr::IsIPAddrAny() const { bool IsIPAddrAny(const NetAddr* addr) {
if (this->raw.family == AF_INET) { if (addr->raw.family == AF_INET) {
if (this->inet.ip == htonl(INADDR_ANY)) { if (addr->inet.ip == htonl(INADDR_ANY)) {
return true; return true;
} }
} else if (this->raw.family == AF_INET6) { } else if (addr->raw.family == AF_INET6) {
if (IPv6ADDR_IS_UNSPECIFIED(&this->inet6.ip)) { if (IPv6ADDR_IS_UNSPECIFIED(&addr->inet6.ip)) {
return true; return true;
} }
if (IPv6ADDR_IS_V4MAPPED(&this->inet6.ip) && if (IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip) &&
IPv6ADDR_V4MAPPED_TO_IPADDR(&this->inet6.ip) == htonl(INADDR_ANY)) { IPv6ADDR_V4MAPPED_TO_IPADDR(&addr->inet6.ip) == htonl(INADDR_ANY)) {
return true; return true;
} }
} }
@@ -178,17 +176,17 @@ bool NetAddr::IsIPAddrAny() const {
NetAddr::NetAddr(const PRNetAddr* prAddr) { PRNetAddrToNetAddr(prAddr, this); } NetAddr::NetAddr(const PRNetAddr* prAddr) { PRNetAddrToNetAddr(prAddr, this); }
bool NetAddr::IsIPAddrV4() const { return this->raw.family == AF_INET; } bool IsIPAddrV4(const NetAddr* addr) { return addr->raw.family == AF_INET; }
bool NetAddr::IsIPAddrV4Mapped() const { bool IsIPAddrV4Mapped(const NetAddr* addr) {
if (this->raw.family == AF_INET6) { if (addr->raw.family == AF_INET6) {
return IPv6ADDR_IS_V4MAPPED(&this->inet6.ip); return IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip);
} }
return false; return false;
} }
bool NetAddr::IsIPAddrLocal() const { bool IsIPAddrLocal(const NetAddr* addr) {
const NetAddr* addr = this; MOZ_ASSERT(addr);
// IPv4 RFC1918 and Link Local Addresses. // IPv4 RFC1918 and Link Local Addresses.
if (addr->raw.family == AF_INET) { if (addr->raw.family == AF_INET) {
@@ -212,8 +210,8 @@ bool NetAddr::IsIPAddrLocal() const {
return false; return false;
} }
bool NetAddr::IsIPAddrShared() const { bool IsIPAddrShared(const NetAddr* addr) {
const NetAddr* addr = this; MOZ_ASSERT(addr);
// IPv4 RFC6598. // IPv4 RFC6598.
if (addr->raw.family == AF_INET) { if (addr->raw.family == AF_INET) {
@@ -227,12 +225,12 @@ bool NetAddr::IsIPAddrShared() const {
return false; return false;
} }
nsresult NetAddr::GetPort(uint16_t* aResult) const { nsresult GetPort(const NetAddr* aAddr, uint16_t* aResult) {
uint16_t port; uint16_t port;
if (this->raw.family == PR_AF_INET) { if (aAddr->raw.family == PR_AF_INET) {
port = this->inet.port; port = aAddr->inet.port;
} else if (this->raw.family == PR_AF_INET6) { } else if (aAddr->raw.family == PR_AF_INET6) {
port = this->inet6.port; port = aAddr->inet6.port;
} else { } else {
return NS_ERROR_NOT_INITIALIZED; return NS_ERROR_NOT_INITIALIZED;
} }

View File

@@ -134,15 +134,6 @@ union NetAddr {
NetAddr() { memset(this, 0, sizeof(NetAddr)); } NetAddr() { memset(this, 0, sizeof(NetAddr)); }
explicit NetAddr(const PRNetAddr* prAddr); explicit NetAddr(const PRNetAddr* prAddr);
bool IsIPAddrAny() const;
bool IsLoopbackAddr() const;
bool IsIPAddrV4() const;
bool IsIPAddrV4Mapped() const;
bool IsIPAddrLocal() const;
bool IsIPAddrShared() const;
nsresult GetPort(uint16_t* aResult) const;
bool ToStringBuffer(char* buf, uint32_t bufSize) const;
}; };
class AddrInfo { class AddrInfo {
@@ -229,6 +220,22 @@ void PRNetAddrToNetAddr(const PRNetAddr* prAddr, NetAddr* addr);
// Does not do a ptr safety check! // Does not do a ptr safety check!
void NetAddrToPRNetAddr(const NetAddr* addr, PRNetAddr* prAddr); void NetAddrToPRNetAddr(const NetAddr* addr, PRNetAddr* prAddr);
bool NetAddrToString(const NetAddr* addr, char* buf, uint32_t bufSize);
bool IsLoopBackAddress(const NetAddr* addr);
bool IsIPAddrAny(const NetAddr* addr);
bool IsIPAddrV4(const NetAddr* addr);
bool IsIPAddrV4Mapped(const NetAddr* addr);
bool IsIPAddrLocal(const NetAddr* addr);
bool IsIPAddrShared(const NetAddr* addr);
nsresult GetPort(const NetAddr* aAddr, uint16_t* aResult);
} // namespace net } // namespace net
} // namespace mozilla } // namespace mozilla

View File

@@ -147,7 +147,7 @@ ChildDNSRecord::GetNextAddrAsString(nsACString& result) {
} }
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
if (addr.ToStringBuffer(buf, sizeof(buf))) { if (NetAddrToString(&addr, buf, sizeof(buf))) {
result.Assign(buf); result.Assign(buf);
return NS_OK; return NS_OK;
} }

View File

@@ -1176,139 +1176,33 @@ nsresult TRR::DohDecode(nsCString& aHost) {
uint16_t arRecords = get16bit(mResponse, 10); uint16_t arRecords = get16bit(mResponse, 10);
LOG(("TRR Decode: %d additional resource records (%u bytes body)\n", LOG(("TRR Decode: %d additional resource records (%u bytes body)\n",
arRecords, mBodySize)); arRecords, mBodySize));
nsClassHashtable<nsCStringHashKey, DOHresp> additionalRecords;
while (arRecords) { while (arRecords) {
nsAutoCString qname; rv = PassQName(index);
rv = GetQname(qname, index);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
LOG(("Bad qname for additional record"));
return rv; return rv;
} }
if (mBodySize < (index + 8)) { if (mBodySize < (index + 8)) {
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
} }
uint16_t type = get16bit(mResponse, index); index += 2; // type
index += 2; index += 2; // class
// The next two bytes encode class index += 4; // ttl
// (or udpPayloadSize when type is TRRTYPE_OPT)
uint16_t cls = get16bit(mResponse, index);
index += 2;
// The next 4 bytes encode TTL
// (or extRCode + ednsVersion + flags when type is TRRTYPE_OPT)
uint32_t ttl = get32bit(mResponse, index);
index += 4;
// cls and ttl are unused when type is TRRTYPE_OPT
// 16 bit RDLENGTH // 16 bit RDLENGTH
if (mBodySize < (index + 2)) { if (mBodySize < (index + 2)) {
LOG(("Record too small"));
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
} }
uint16_t RDLENGTH = get16bit(mResponse, index);
uint16_t rdlength = get16bit(mResponse, index);
index += 2; index += 2;
if (mBodySize < (index + rdlength)) { if (mBodySize < (index + RDLENGTH)) {
LOG(("rdlength too big"));
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
} }
index += RDLENGTH;
auto parseRecord = [&]() {
LOG(("Parsing additional record type: %u", type));
auto& entry = additionalRecords.GetOrInsert(qname);
if (!entry) {
entry.reset(new DOHresp());
}
switch (type) {
case TRRTYPE_A:
if (kDNS_CLASS_IN != cls) {
LOG(("NOT IN - returning"));
return;
}
if (rdlength != 4) {
LOG(("TRR bad length for A (%u)\n", rdlength));
return;
}
rv = entry->Add(ttl, mResponse, index, rdlength, mAllowRFC1918);
if (NS_FAILED(rv)) {
LOG(
("TRR:DohDecode failed: local IP addresses or unknown IP "
"family\n"));
return;
}
break;
case TRRTYPE_AAAA:
if (kDNS_CLASS_IN != cls) {
LOG(("NOT IN - returning"));
return;
}
if (rdlength != 16) {
LOG(("TRR bad length for AAAA (%u)\n", rdlength));
return;
}
rv = entry->Add(ttl, mResponse, index, rdlength, mAllowRFC1918);
if (NS_FAILED(rv)) {
LOG(("TRR got unique/local IPv6 address!\n"));
return;
}
break;
case TRRTYPE_OPT: { // OPT
LOG(("Parsing opt rdlen: %u", rdlength));
unsigned int offset = 0;
while (offset + 2 <= rdlength) {
uint16_t optCode = get16bit(mResponse, index + offset);
LOG(("optCode: %u", optCode));
offset += 2;
if (offset + 2 > rdlength) {
break;
}
uint16_t optLen = get16bit(mResponse, index + offset);
LOG(("optLen: %u", optLen));
offset += 2;
if (offset + optLen > rdlength) {
LOG(("offset: %u, optLen: %u, rdlen: %u", offset, optLen,
rdlength));
break;
}
LOG(("OPT: code: %u len:%u", optCode, optLen));
if (optCode != 15) {
offset += optLen;
continue;
}
// optCode == 15; Extended DNS error
if (offset + 2 > rdlength || optLen < 2) {
break;
}
mExtendedError = get16bit(mResponse, index + offset);
LOG((
"Extended error code: %u message: %s", mExtendedError,
nsAutoCString((char*)mResponse + index + offset + 2, optLen - 2)
.get()));
offset += optLen;
}
break;
}
default:
break;
}
};
parseRecord();
index += rdlength;
LOG(("done with additional rr now %u of %u\n", index, mBodySize)); LOG(("done with additional rr now %u of %u\n", index, mBodySize));
arRecords--; arRecords--;
} }
SaveAdditionalRecords(additionalRecords);
if (index != mBodySize) { if (index != mBodySize) {
LOG(("DohDecode failed to parse entire response body, %u out of %u bytes\n", LOG(("DohDecode failed to parse entire response body, %u out of %u bytes\n",
index, mBodySize)); index, mBodySize));
@@ -1316,8 +1210,8 @@ nsresult TRR::DohDecode(nsCString& aHost) {
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
} }
if ((mType != TRRTYPE_NS) && mCname.IsEmpty() && mDNS.mAddresses.IsEmpty() && if ((mType != TRRTYPE_NS) && mCname.IsEmpty() &&
mResult.is<TypeRecordEmpty>()) { !mDNS.mAddresses.getFirst() && mResult.is<TypeRecordEmpty>()) {
// no entries were stored! // no entries were stored!
LOG(("TRR: No entries were stored!\n")); LOG(("TRR: No entries were stored!\n"));
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@@ -1335,45 +1229,6 @@ nsresult TRR::DohDecode(nsCString& aHost) {
return NS_OK; return NS_OK;
} }
void TRR::SaveAdditionalRecords(
const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords) {
if (!mRec) {
return;
}
nsresult rv;
for (auto iter = aRecords.ConstIter(); !iter.Done(); iter.Next()) {
if (iter.Data() && iter.Data()->mAddresses.IsEmpty()) {
// no point in adding empty records.
continue;
}
RefPtr<nsHostRecord> hostRecord;
rv = mHostResolver->GetHostRecord(
iter.Key(), EmptyCString(), nsIDNSService::RESOLVE_TYPE_DEFAULT,
mRec->flags, AF_UNSPEC, mRec->pb, mRec->originSuffix,
getter_AddRefs(hostRecord));
if (NS_FAILED(rv)) {
LOG(("Failed to get host record for additional record %s",
nsCString(iter.Key()).get()));
continue;
}
RefPtr<AddrInfo> ai(new AddrInfo(iter.Key(), TRRTYPE_A,
std::move(iter.Data()->mAddresses),
iter.Data()->mTtl));
// Since we're not actually calling NameLookup for this record, we need
// to set these fields to avoid assertions in CompleteLookup.
// This is quite hacky, and should be fixed.
hostRecord->mResolving++;
hostRecord->mEffectiveTRRMode = mRec->mEffectiveTRRMode;
RefPtr<AddrHostRecord> addrRec = do_QueryObject(hostRecord);
addrRec->mTrrStart = TimeStamp::Now();
addrRec->mTrrA = this; // Hack!
LOG(("Completing lookup for additional: %s", nsCString(iter.Key()).get()));
(void)mHostResolver->CompleteLookup(hostRecord, NS_OK, ai, mPB,
mOriginSuffix, AddrHostRecord::TRR_OK);
}
}
nsresult TRR::ParseSvcParam(unsigned int svcbIndex, uint16_t key, nsresult TRR::ParseSvcParam(unsigned int svcbIndex, uint16_t key,
SvcFieldValue& field, uint16_t length) { SvcFieldValue& field, uint16_t length) {
switch (key) { switch (key) {
@@ -1515,10 +1370,21 @@ void TRR::StoreIPHintAsDNSRecord(const struct SVCB& aSVCBRecord) {
nsresult TRR::ReturnData(nsIChannel* aChannel) { nsresult TRR::ReturnData(nsIChannel* aChannel) {
if (mType != TRRTYPE_TXT && mType != TRRTYPE_HTTPSSVC) { if (mType != TRRTYPE_TXT && mType != TRRTYPE_HTTPSSVC) {
// create and populate an AddrInfo instance to pass on // create and populate an AddrInfo instance to pass on
RefPtr<AddrInfo> ai( DOHaddr* item;
new AddrInfo(mHost, mType, nsTArray<NetAddr>(), mDNS.mTtl)); uint32_t ttl = AddrInfo::NO_TTL_DATA;
nsTArray<NetAddr> addresses;
while ((item = static_cast<DOHaddr*>(mDNS.mAddresses.popFirst()))) {
addresses.AppendElement(item->mNet);
if (item->mTtl < ttl) {
// While the DNS packet might return individual TTLs for each address,
// we can only return one value in the AddrInfo class so pick the
// lowest number.
ttl = item->mTtl;
}
}
RefPtr<AddrInfo> ai(new AddrInfo(mHost, mType, nsTArray<NetAddr>(), ttl));
auto builder = ai->Build(); auto builder = ai->Build();
builder.SetAddresses(std::move(mDNS.mAddresses)); builder.SetAddresses(std::move(addresses));
// Set timings. // Set timings.
nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel); nsCOMPtr<nsITimedChannel> timedChan = do_QueryInterface(aChannel);
@@ -1550,31 +1416,6 @@ nsresult TRR::ReturnData(nsIChannel* aChannel) {
return NS_OK; return NS_OK;
} }
// https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-extended-error-16#section-4
// This is a list of errors for which we should not fallback to Do53.
// These are normally DNSSEC failures or explicit filtering performed by the
// recursive resolver.
bool hardFail(uint16_t code) {
const uint16_t noFallbackErrors[] = {
4, // Forged answer (malware filtering)
6, // DNSSEC Boggus
7, // Signature expired
8, // Signature not yet valid
9, // DNSKEY Missing
10, // RRSIG missing
11, // No ZONE Key Bit set
12, // NSEC Missing
17, // Filtered
};
for (const auto& err : noFallbackErrors) {
if (code == err) {
return true;
}
}
return false;
}
nsresult TRR::FailData(nsresult error) { nsresult TRR::FailData(nsresult error) {
if (!mHostResolver) { if (!mHostResolver) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@@ -1583,10 +1424,6 @@ nsresult TRR::FailData(nsresult error) {
// If we didn't record a reason until now, record a default one. // If we didn't record a reason until now, record a default one.
RecordReason(nsHostRecord::TRR_FAILED); RecordReason(nsHostRecord::TRR_FAILED);
if (mExtendedError != UINT16_MAX && hardFail(mExtendedError)) {
error = NS_ERROR_DEFINITIVE_UNKNOWN_HOST;
}
if (mType == TRRTYPE_TXT || mType == TRRTYPE_HTTPSSVC) { if (mType == TRRTYPE_TXT || mType == TRRTYPE_HTTPSSVC) {
TypeRecordResultType empty(Nothing{}); TypeRecordResultType empty(Nothing{});
(void)mHostResolver->CompleteLookupByType(mRec, error, empty, 0, mPB); (void)mHostResolver->CompleteLookupByType(mRec, error, empty, 0, mPB);
@@ -1608,7 +1445,7 @@ nsresult TRR::FailData(nsresult error) {
nsresult TRR::FollowCname(nsIChannel* aChannel) { nsresult TRR::FollowCname(nsIChannel* aChannel) {
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsAutoCString cname; nsAutoCString cname;
while (NS_SUCCEEDED(rv) && mDNS.mAddresses.IsEmpty() && !mCname.IsEmpty() && while (NS_SUCCEEDED(rv) && !mDNS.mAddresses.getFirst() && !mCname.IsEmpty() &&
mCnameLoop > 0) { mCnameLoop > 0) {
mCnameLoop--; mCnameLoop--;
LOG(("TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(), LOG(("TRR::On200Response CNAME %s => %s (%u)\n", mHost.get(), mCname.get(),
@@ -1626,7 +1463,7 @@ nsresult TRR::FollowCname(nsIChannel* aChannel) {
// restore mCname as DohDecode() change it // restore mCname as DohDecode() change it
mCname = cname; mCname = cname;
if (NS_SUCCEEDED(rv) && !mDNS.mAddresses.IsEmpty()) { if (NS_SUCCEEDED(rv) && mDNS.mAddresses.getFirst()) {
ReturnData(aChannel); ReturnData(aChannel);
return NS_OK; return NS_OK;
} }
@@ -1656,7 +1493,7 @@ nsresult TRR::On200Response(nsIChannel* aChannel) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!mDNS.mAddresses.IsEmpty() || mType == TRRTYPE_TXT || mCname.IsEmpty()) { if (mDNS.mAddresses.getFirst() || mType == TRRTYPE_TXT || mCname.IsEmpty()) {
// pass back the response data // pass back the response data
ReturnData(aChannel); ReturnData(aChannel);
return NS_OK; return NS_OK;
@@ -1781,42 +1618,37 @@ TRR::OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
nsresult DOHresp::Add(uint32_t TTL, unsigned char* dns, unsigned int index, nsresult DOHresp::Add(uint32_t TTL, unsigned char* dns, unsigned int index,
uint16_t len, bool aLocalAllowed) { uint16_t len, bool aLocalAllowed) {
NetAddr addr; auto doh = MakeUnique<DOHaddr>();
NetAddr* addr = &doh->mNet;
if (4 == len) { if (4 == len) {
// IPv4 // IPv4
addr.inet.family = AF_INET; addr->inet.family = AF_INET;
addr.inet.port = 0; // unknown addr->inet.port = 0; // unknown
addr.inet.ip = ntohl(get32bit(dns, index)); addr->inet.ip = ntohl(get32bit(dns, index));
} else if (16 == len) { } else if (16 == len) {
// IPv6 // IPv6
addr.inet6.family = AF_INET6; addr->inet6.family = AF_INET6;
addr.inet6.port = 0; // unknown addr->inet6.port = 0; // unknown
addr.inet6.flowinfo = 0; // unknown addr->inet6.flowinfo = 0; // unknown
addr.inet6.scope_id = 0; // unknown addr->inet6.scope_id = 0; // unknown
for (int i = 0; i < 16; i++, index++) { for (int i = 0; i < 16; i++, index++) {
addr.inet6.ip.u8[i] = dns[index]; addr->inet6.ip.u8[i] = dns[index];
} }
} else { } else {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
if (addr.IsIPAddrLocal() && !aLocalAllowed) { if (IsIPAddrLocal(addr) && !aLocalAllowed) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
doh->mTtl = TTL;
// While the DNS packet might return individual TTLs for each address,
// we can only return one value in the AddrInfo class so pick the
// lowest number.
if (mTtl < TTL) {
mTtl = TTL;
}
if (LOG_ENABLED()) { if (LOG_ENABLED()) {
char buf[128]; char buf[128];
addr.ToStringBuffer(buf, sizeof(buf)); NetAddrToString(addr, buf, sizeof(buf));
LOG(("DOHresp:Add %s\n", buf)); LOG(("DOHresp:Add %s\n", buf));
} }
mAddresses.AppendElement(addr); mAddresses.insertBack(doh.release());
return NS_OK; return NS_OK;
} }

View File

@@ -9,7 +9,6 @@
#include "mozilla/net/DNSByTypeRecord.h" #include "mozilla/net/DNSByTypeRecord.h"
#include "mozilla/Assertions.h" #include "mozilla/Assertions.h"
#include "nsClassHashtable.h"
#include "nsIChannel.h" #include "nsIChannel.h"
#include "nsIHttpPushListener.h" #include "nsIHttpPushListener.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
@@ -27,21 +26,31 @@ enum TrrType {
TRRTYPE_NS = 2, TRRTYPE_NS = 2,
TRRTYPE_CNAME = 5, TRRTYPE_CNAME = 5,
TRRTYPE_AAAA = 28, TRRTYPE_AAAA = 28,
TRRTYPE_OPT = 41,
TRRTYPE_TXT = 16, TRRTYPE_TXT = 16,
TRRTYPE_HTTPSSVC = nsIDNSService::RESOLVE_TYPE_HTTPSSVC, // 65 TRRTYPE_HTTPSSVC = nsIDNSService::RESOLVE_TYPE_HTTPSSVC, // 65
}; };
class DOHaddr : public LinkedListElement<DOHaddr> {
public:
NetAddr mNet;
uint32_t mTtl;
};
class TRRService; class TRRService;
class TRRServiceChannel; class TRRServiceChannel;
extern TRRService* gTRRService; extern TRRService* gTRRService;
class DOHresp { class DOHresp {
public: public:
~DOHresp() {
DOHaddr* el;
while ((el = mAddresses.popLast())) {
delete el;
}
}
nsresult Add(uint32_t TTL, unsigned char* dns, unsigned int index, nsresult Add(uint32_t TTL, unsigned char* dns, unsigned int index,
uint16_t len, bool aLocalAllowed); uint16_t len, bool aLocalAllowed);
nsTArray<NetAddr> mAddresses; LinkedList<DOHaddr> mAddresses;
uint32_t mTtl = UINT32_MAX;
}; };
class TRR : public Runnable, class TRR : public Runnable,
@@ -146,8 +155,6 @@ class TRR : public Runnable,
nsresult FollowCname(nsIChannel* aChannel); nsresult FollowCname(nsIChannel* aChannel);
bool UseDefaultServer(); bool UseDefaultServer();
void SaveAdditionalRecords(
const nsClassHashtable<nsCStringHashKey, DOHresp>& aRecords);
nsresult CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult); nsresult CreateChannelHelper(nsIURI* aUri, nsIChannel** aResult);
@@ -172,7 +179,6 @@ class TRR : public Runnable,
uint32_t mCnameLoop = kCnameChaseMax; // loop detection counter uint32_t mCnameLoop = kCnameChaseMax; // loop detection counter
bool mAllowRFC1918 = false; bool mAllowRFC1918 = false;
uint16_t mExtendedError = UINT16_MAX;
uint32_t mTTL = UINT32_MAX; uint32_t mTTL = UINT32_MAX;
TypeRecordResultType mResult = mozilla::AsVariant(Nothing()); TypeRecordResultType mResult = mozilla::AsVariant(Nothing());

View File

@@ -291,7 +291,7 @@ nsDNSRecord::GetNextAddrAsString(nsACString& result) {
} }
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
if (addr.ToStringBuffer(buf, sizeof(buf))) { if (NetAddrToString(&addr, buf, sizeof(buf))) {
result.Assign(buf); result.Assign(buf);
return NS_OK; return NS_OK;
} }

View File

@@ -311,7 +311,7 @@ bool AddrHostRecord::Blacklisted(const NetAddr* aQuery) {
} }
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
if (!aQuery->ToStringBuffer(buf, sizeof(buf))) { if (!NetAddrToString(aQuery, buf, sizeof(buf))) {
return false; return false;
} }
nsDependentCString strQuery(buf); nsDependentCString strQuery(buf);
@@ -336,7 +336,7 @@ void AddrHostRecord::ReportUnusable(const NetAddr* aAddress) {
++mBlacklistedCount; ++mBlacklistedCount;
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
if (aAddress->ToStringBuffer(buf, sizeof(buf))) { if (NetAddrToString(aAddress, buf, sizeof(buf))) {
LOG( LOG(
("Successfully adding address [%s] to blacklist for host " ("Successfully adding address [%s] to blacklist for host "
"[%s].\n", "[%s].\n",
@@ -2011,9 +2011,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
if (NS_FAILED(addrRec->mFirstTRRresult) && NS_FAILED(status) && if (NS_FAILED(addrRec->mFirstTRRresult) && NS_FAILED(status) &&
(addrRec->mFirstTRRresult != NS_ERROR_UNKNOWN_HOST) && (addrRec->mFirstTRRresult != NS_ERROR_UNKNOWN_HOST) &&
(status != NS_ERROR_UNKNOWN_HOST) && (status != NS_ERROR_UNKNOWN_HOST)) {
(addrRec->mFirstTRRresult != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) &&
(status != NS_ERROR_DEFINITIVE_UNKNOWN_HOST)) {
// the errors are not failed resolves, that means // the errors are not failed resolves, that means
// something else failed, consider this as *TRR not used* // something else failed, consider this as *TRR not used*
// for actually trying to resolve the host // for actually trying to resolve the host
@@ -2040,8 +2038,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
} }
if (!addrRec->mTRRSuccess && if (!addrRec->mTRRSuccess &&
addrRec->mEffectiveTRRMode == nsIRequest::TRR_FIRST_MODE && addrRec->mEffectiveTRRMode == nsIRequest::TRR_FIRST_MODE) {
addrRec->mFirstTRRresult != NS_ERROR_DEFINITIVE_UNKNOWN_HOST) {
MOZ_ASSERT(!addrRec->mResolving); MOZ_ASSERT(!addrRec->mResolving);
NativeLookup(addrRec); NativeLookup(addrRec);
MOZ_ASSERT(addrRec->mResolving); MOZ_ASSERT(addrRec->mResolving);
@@ -2106,7 +2103,7 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup(
if (addrRec->addr_info) { if (addrRec->addr_info) {
for (const auto& elem : addrRec->addr_info->Addresses()) { for (const auto& elem : addrRec->addr_info->Addresses()) {
char buf[128]; char buf[128];
elem.ToStringBuffer(buf, sizeof(buf)); NetAddrToString(&elem, buf, sizeof(buf));
LOG(("CompleteLookup: %s has %s\n", addrRec->host.get(), buf)); LOG(("CompleteLookup: %s has %s\n", addrRec->host.get(), buf));
} }
} else { } else {
@@ -2421,7 +2418,7 @@ void nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries>* args) {
MutexAutoLock lock(addrRec->addr_info_lock); MutexAutoLock lock(addrRec->addr_info_lock);
for (const auto& addr : addrRec->addr_info->Addresses()) { for (const auto& addr : addrRec->addr_info->Addresses()) {
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
if (addr.ToStringBuffer(buf, sizeof(buf))) { if (NetAddrToString(&addr, buf, sizeof(buf))) {
info.hostaddr.AppendElement(buf); info.hostaddr.AppendElement(buf);
} }
} }

View File

@@ -1219,9 +1219,9 @@ nsresult nsFtpState::S_pasv() {
if (sTrans) { if (sTrans) {
nsresult rv = sTrans->GetPeerAddr(&mServerAddress); nsresult rv = sTrans->GetPeerAddr(&mServerAddress);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
if (!mServerAddress.IsIPAddrAny()) if (!IsIPAddrAny(&mServerAddress))
mServerIsIPv6 = (mServerAddress.raw.family == AF_INET6) && mServerIsIPv6 = (mServerAddress.raw.family == AF_INET6) &&
!mServerAddress.IsIPAddrV4Mapped(); !IsIPAddrV4Mapped(&mServerAddress);
else { else {
/* /*
* In case of SOCKS5 remote DNS resolution, we do * In case of SOCKS5 remote DNS resolution, we do
@@ -1234,7 +1234,7 @@ nsresult nsFtpState::S_pasv() {
rv = sTrans->GetSelfAddr(&selfAddress); rv = sTrans->GetSelfAddr(&selfAddress);
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
mServerIsIPv6 = (selfAddress.raw.family == AF_INET6) && mServerIsIPv6 = (selfAddress.raw.family == AF_INET6) &&
!selfAddress.IsIPAddrV4Mapped(); !IsIPAddrV4Mapped(&selfAddress);
} }
} }
} }
@@ -1351,9 +1351,9 @@ nsFtpState::R_pasv() {
nsCOMPtr<nsISocketTransport> strans; nsCOMPtr<nsISocketTransport> strans;
nsAutoCString host; nsAutoCString host;
if (!mServerAddress.IsIPAddrAny()) { if (!IsIPAddrAny(&mServerAddress)) {
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
mServerAddress.ToStringBuffer(buf, sizeof(buf)); NetAddrToString(&mServerAddress, buf, sizeof(buf));
host.Assign(buf); host.Assign(buf);
} else { } else {
/* /*

View File

@@ -98,7 +98,7 @@ nsresult Http3Session::Init(const nsACString& aOrigin,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
selfAddr.ToStringBuffer(buf, kIPv6CStrBufSize); NetAddrToString(&selfAddr, buf, kIPv6CStrBufSize);
nsAutoCString selfAddrStr; nsAutoCString selfAddrStr;
if (selfAddr.raw.family == AF_INET6) { if (selfAddr.raw.family == AF_INET6) {
@@ -119,7 +119,7 @@ nsresult Http3Session::Init(const nsACString& aOrigin,
LOG3(("Http3Session::Init GetPeerAddr failed [this=%p]", this)); LOG3(("Http3Session::Init GetPeerAddr failed [this=%p]", this));
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
peerAddr.ToStringBuffer(buf, kIPv6CStrBufSize); NetAddrToString(&peerAddr, buf, kIPv6CStrBufSize);
nsAutoCString peerAddrStr; nsAutoCString peerAddrStr;
if (peerAddr.raw.family == AF_INET6) { if (peerAddr.raw.family == AF_INET6) {

View File

@@ -2491,7 +2491,7 @@ HttpBaseChannel::GetLocalAddress(nsACString& addr) {
if (mSelfAddr.raw.family == PR_AF_UNSPEC) return NS_ERROR_NOT_AVAILABLE; if (mSelfAddr.raw.family == PR_AF_UNSPEC) return NS_ERROR_NOT_AVAILABLE;
addr.SetLength(kIPv6CStrBufSize); addr.SetLength(kIPv6CStrBufSize);
mSelfAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize); NetAddrToString(&mSelfAddr, addr.BeginWriting(), kIPv6CStrBufSize);
addr.SetLength(strlen(addr.BeginReading())); addr.SetLength(strlen(addr.BeginReading()));
return NS_OK; return NS_OK;
@@ -2586,7 +2586,7 @@ HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
if (mPeerAddr.raw.family == PR_AF_UNSPEC) return NS_ERROR_NOT_AVAILABLE; if (mPeerAddr.raw.family == PR_AF_UNSPEC) return NS_ERROR_NOT_AVAILABLE;
addr.SetLength(kIPv6CStrBufSize); addr.SetLength(kIPv6CStrBufSize);
mPeerAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize); NetAddrToString(&mPeerAddr, addr.BeginWriting(), kIPv6CStrBufSize);
addr.SetLength(strlen(addr.BeginReading())); addr.SetLength(strlen(addr.BeginReading()));
return NS_OK; return NS_OK;

View File

@@ -1632,7 +1632,7 @@ HttpChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
isLocal = (peerAddr.raw.family == PR_AF_LOCAL); isLocal = (peerAddr.raw.family == PR_AF_LOCAL);
#endif #endif
isLocal = isLocal || peerAddr.IsLoopbackAddr(); isLocal = isLocal || IsLoopBackAddress(&peerAddr);
if (!isLocal) { if (!isLocal) {
if (!mHasSuspendedByBackPressure) { if (!mHasSuspendedByBackPressure) {

View File

@@ -559,7 +559,7 @@ bool nsHttpConnectionInfo::HostIsLocalIPLiteral() const {
return false; return false;
} }
NetAddr netAddr(&prAddr); NetAddr netAddr(&prAddr);
return netAddr.IsIPAddrLocal(); return IsIPAddrLocal(&netAddr);
} }
} // namespace net } // namespace net

View File

@@ -5296,7 +5296,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport* trans,
for (uint32_t i = 0; i < addressSet.Length(); ++i) { for (uint32_t i = 0; i < addressSet.Length(); ++i) {
nsCString* newKey = mEnt->mCoalescingKeys.AppendElement(nsCString()); nsCString* newKey = mEnt->mCoalescingKeys.AppendElement(nsCString());
newKey->SetLength(kIPv6CStrBufSize + 26); newKey->SetLength(kIPv6CStrBufSize + 26);
addressSet[i].ToStringBuffer(newKey->BeginWriting(), kIPv6CStrBufSize); NetAddrToString(&addressSet[i], newKey->BeginWriting(),
kIPv6CStrBufSize);
newKey->SetLength(strlen(newKey->BeginReading())); newKey->SetLength(strlen(newKey->BeginReading()));
if (mEnt->mConnInfo->GetAnonymous()) { if (mEnt->mConnInfo->GetAnonymous()) {
newKey->AppendLiteral("~A:"); newKey->AppendLiteral("~A:");

View File

@@ -545,7 +545,7 @@ PRStatus nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc* fd) {
if (MOZ_LOG_TEST(gSOCKSLog, LogLevel::Debug)) { if (MOZ_LOG_TEST(gSOCKSLog, LogLevel::Debug)) {
char buf[kIPv6CStrBufSize]; char buf[kIPv6CStrBufSize];
mInternalProxyAddr.ToStringBuffer(buf, sizeof(buf)); NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
LOGDEBUG(("socks: trying proxy server, %s:%hu", buf, LOGDEBUG(("socks: trying proxy server, %s:%hu", buf,
ntohs(mInternalProxyAddr.inet.port))); ntohs(mInternalProxyAddr.inet.port)));
} }

View File

@@ -147,7 +147,6 @@ class TRRDNSListener {
this.expectedAnswer, this.expectedAnswer,
`Checking result for ${this.name}` `Checking result for ${this.name}`
); );
inRecord.rewind(); // In case the caller also checks the addresses
if (this.delay !== undefined) { if (this.delay !== undefined) {
Assert.greaterOrEqual( Assert.greaterOrEqual(
@@ -269,39 +268,23 @@ function trrQueryHandler(req, resp, url) {
function processRequest(req, resp, payload) { function processRequest(req, resp, payload) {
let dnsQuery = global.dnsPacket.decode(payload); let dnsQuery = global.dnsPacket.decode(payload);
let response = let answers =
global.dns_query_answers[ global.dns_query_answers[
`${dnsQuery.questions[0].name}/${dnsQuery.questions[0].type}` `${dnsQuery.questions[0].name}/${dnsQuery.questions[0].type}`
] || {}; ] || [];
let buf = global.dnsPacket.encode({ let buf = global.dnsPacket.encode({
type: "response", type: "response",
id: dnsQuery.id, id: dnsQuery.id,
flags: global.dnsPacket.RECURSION_DESIRED, flags: global.dnsPacket.RECURSION_DESIRED,
questions: dnsQuery.questions, questions: dnsQuery.questions,
answers: response.answers || [], answers,
additionals: response.additionals || [],
}); });
let writeResponse = (resp, buf) => {
resp.setHeader("Content-Length", buf.length); resp.setHeader("Content-Length", buf.length);
resp.writeHead(200, { "Content-Type": "application/dns-message" }); resp.writeHead(200, { "Content-Type": "application/dns-message" });
resp.write(buf); resp.write(buf);
resp.end(""); resp.end("");
};
if (response.delay) {
setTimeout(
arg => {
writeResponse(arg[0], arg[1]);
},
response.delay,
[resp, buf]
);
return;
}
writeResponse(resp, buf);
} }
} }
@@ -350,12 +333,10 @@ class TRRServer {
/// flush: false, /// flush: false,
/// data: "1.2.3.4", /// data: "1.2.3.4",
/// }] /// }]
async registerDoHAnswers(name, type, answers, additionals, delay = 0) { async registerDoHAnswers(name, type, answers) {
let text = `global.dns_query_answers["${name}/${type}"] = ${JSON.stringify({ let text = `global.dns_query_answers["${name}/${type}"] = ${JSON.stringify(
answers, answers
additionals, )}`;
delay,
})}`;
return this.execute(text); return this.execute(text);
} }
} }

View File

@@ -1,276 +0,0 @@
/* 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/. */
"use strict";
const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
Ci.nsIDNSService
);
trr_test_setup();
registerCleanupFunction(async () => {
trr_clear_prefs();
});
function makeChan(url) {
let chan = NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true,
}).QueryInterface(Ci.nsIHttpChannel);
return chan;
}
let processId;
function channelOpenPromise(chan) {
return new Promise(resolve => {
function finish(req, buffer) {
resolve([req, buffer]);
}
chan.asyncOpen(new ChannelListener(finish));
});
}
add_task(async function test_parse_additional_section() {
let trrServer = new TRRServer();
registerCleanupFunction(async () => trrServer.stop());
await trrServer.start();
dump(`port = ${trrServer.port}\n`);
let chan = makeChan(`https://localhost:${trrServer.port}/test?bla=some`);
let [req, resp] = await channelOpenPromise(chan);
equal(resp, "<h1> 404 Path not found: /test?bla=some</h1>");
dns.clearCache(true);
Services.prefs.setIntPref("network.trr.mode", 3);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port}/dns-query`
);
await trrServer.registerDoHAnswers(
"something.foo",
"A",
[
{
name: "something.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
],
[
{
name: "else.foo",
ttl: 55,
type: "A",
flush: false,
data: "2.3.4.5",
},
]
);
await new TRRDNSListener("something.foo", "1.2.3.4");
await new TRRDNSListener("else.foo", "2.3.4.5");
await trrServer.registerDoHAnswers(
"a.foo",
"A",
[
{
name: "a.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
],
[
{
name: "b.foo",
ttl: 55,
type: "A",
flush: false,
data: "2.3.4.5",
},
]
);
await trrServer.registerDoHAnswers("b.foo", "A", [
{
name: "b.foo",
ttl: 55,
type: "A",
flush: false,
data: "3.4.5.6",
},
]);
let req1 = new TRRDNSListener("a.foo", "1.2.3.4");
// A request for b.foo will be in progress by the time we parse the additional
// record. To keep things simple we don't end up saving the record, instead
// we wait for the in-progress request to complete.
// This check is also racy - if the response for a.foo completes before we make
// this request, we'll put the other IP in the cache. But that is very unlikely.
let req2 = new TRRDNSListener("b.foo", "3.4.5.6");
await Promise.all([req1, req2]);
// IPv6 additional
await trrServer.registerDoHAnswers(
"xyz.foo",
"A",
[
{
name: "xyz.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
],
[
{
name: "abc.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::1:2:3:4",
},
]
);
await new TRRDNSListener("xyz.foo", "1.2.3.4");
await new TRRDNSListener("abc.foo", "::1:2:3:4");
// IPv6 additional
await trrServer.registerDoHAnswers(
"ipv6.foo",
"AAAA",
[
{
name: "ipv6.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::abcd",
},
],
[
{
name: "def.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::a:b:c:d",
},
]
);
await new TRRDNSListener("ipv6.foo", "::abcd");
await new TRRDNSListener("def.foo", "::a:b:c:d");
// IPv6 additional
await trrServer.registerDoHAnswers(
"ipv6b.foo",
"AAAA",
[
{
name: "ipv6b.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::abcd",
},
],
[
{
name: "qqqq.foo",
ttl: 55,
type: "A",
flush: false,
data: "9.8.7.6",
},
]
);
await new TRRDNSListener("ipv6b.foo", "::abcd");
await new TRRDNSListener("qqqq.foo", "9.8.7.6");
// Multiple IPs and multiple additional records
await trrServer.registerDoHAnswers(
"multiple.foo",
"A",
[
{
name: "multiple.foo",
ttl: 55,
type: "A",
flush: false,
data: "9.9.9.9",
},
],
[
{
// Should be ignored, because it should be in the answer section
name: "multiple.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.1.1.1",
},
{
// Is ignored, because it should be in the answer section
name: "multiple.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::abcd",
},
{
name: "yuiop.foo",
ttl: 55,
type: "AAAA",
flush: false,
data: "::abcd",
},
{
name: "yuiop.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
]
);
let [inRequest, inRecord, inStatus] = await new TRRDNSListener(
"multiple.foo",
"9.9.9.9"
);
let IPs = [];
inRecord.QueryInterface(Ci.nsIDNSAddrRecord);
inRecord.rewind();
while (inRecord.hasMore()) {
IPs.push(inRecord.getNextAddrAsString());
}
equal(IPs.length, 1);
equal(IPs[0], "9.9.9.9");
IPs = [];
[inRequest, inRecord, inStatus] = await new TRRDNSListener(
"yuiop.foo",
undefined,
false
);
inRecord.QueryInterface(Ci.nsIDNSAddrRecord);
inRecord.rewind();
while (inRecord.hasMore()) {
IPs.push(inRecord.getNextAddrAsString());
}
equal(IPs.length, 2);
equal(IPs[0], "::abcd");
equal(IPs[1], "1.2.3.4");
await trrServer.stop();
});

View File

@@ -1,304 +0,0 @@
/* 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/. */
"use strict";
const dns = Cc["@mozilla.org/network/dns-service;1"].getService(
Ci.nsIDNSService
);
trr_test_setup();
registerCleanupFunction(async () => {
trr_clear_prefs();
});
function makeChan(url) {
let chan = NetUtil.newChannel({
uri: url,
loadUsingSystemPrincipal: true,
}).QueryInterface(Ci.nsIHttpChannel);
return chan;
}
let processId;
function channelOpenPromise(chan) {
return new Promise(resolve => {
function finish(req, buffer) {
resolve([req, buffer]);
}
chan.asyncOpen(new ChannelListener(finish));
});
}
let trrServer;
add_task(async function setup() {
trrServer = new TRRServer();
registerCleanupFunction(async () => trrServer.stop());
await trrServer.start();
dump(`port = ${trrServer.port}\n`);
let chan = makeChan(`https://localhost:${trrServer.port}/test?bla=some`);
let [req, resp] = await channelOpenPromise(chan);
equal(resp, "<h1> 404 Path not found: /test?bla=some</h1>");
dns.clearCache(true);
Services.prefs.setIntPref("network.trr.mode", 2);
Services.prefs.setCharPref(
"network.trr.uri",
`https://foo.example.com:${trrServer.port}/dns-query`
);
});
add_task(async function test_extended_error_bogus() {
await trrServer.registerDoHAnswers("something.foo", "A", [
{
name: "something.foo",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
]);
await new TRRDNSListener("something.foo", "1.2.3.4");
await trrServer.registerDoHAnswers(
"a.foo",
"A",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 6, // DNSSEC_BOGUS
text: "DNSSec bogus",
},
],
},
]
);
// Check that we don't fall back to DNS
let [, , inStatus] = await new TRRDNSListener("a.foo", undefined, false);
Assert.ok(
!Components.isSuccessCode(inStatus),
`${inStatus} should be an error code`
);
});
add_task(async function test_extended_error_filtered() {
await trrServer.registerDoHAnswers(
"b.foo",
"A",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 17, // Filtered
text: "Filtered",
},
],
},
]
);
// Check that we don't fall back to DNS
let [, , inStatus] = await new TRRDNSListener("b.foo", undefined, false);
Assert.ok(
!Components.isSuccessCode(inStatus),
`${inStatus} should be an error code`
);
});
add_task(async function test_extended_error_not_ready() {
await trrServer.registerDoHAnswers(
"c.foo",
"A",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 14, // Not ready
text: "Not ready",
},
],
},
]
);
// For this code it's OK to fallback
await new TRRDNSListener("c.foo", "127.0.0.1");
});
add_task(async function ipv6_answer_and_delayed_ipv4_error() {
// AAAA comes back immediately.
// A EDNS_ERROR comes back later, with a delay
await trrServer.registerDoHAnswers("delay1.com", "AAAA", [
{
name: "delay1.com",
ttl: 55,
type: "AAAA",
flush: false,
data: "::a:b:c:d",
},
]);
await trrServer.registerDoHAnswers(
"delay1.com",
"A",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 17, // Filtered
text: "Filtered",
},
],
},
],
200 // delay
);
// Check that we don't fall back to DNS
await new TRRDNSListener("delay1.com", "::a:b:c:d");
});
add_task(async function ipv4_error_and_delayed_ipv6_answer() {
// AAAA comes back immediately delay
// A EDNS_ERROR comes back immediately
await trrServer.registerDoHAnswers(
"delay2.com",
"AAAA",
[
{
name: "delay2.com",
ttl: 55,
type: "AAAA",
flush: false,
data: "::a:b:c:d",
},
],
[],
200 // delay
);
await trrServer.registerDoHAnswers(
"delay2.com",
"A",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 17, // Filtered
text: "Filtered",
},
],
},
]
);
// Check that we don't fall back to DNS
await new TRRDNSListener("delay2.com", "::a:b:c:d");
});
add_task(async function ipv4_answer_and_delayed_ipv6_error() {
// A comes back immediately.
// AAAA EDNS_ERROR comes back later, with a delay
await trrServer.registerDoHAnswers("delay3.com", "A", [
{
name: "delay3.com",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
]);
await trrServer.registerDoHAnswers(
"delay3.com",
"AAAA",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 17, // Filtered
text: "Filtered",
},
],
},
],
200 // delay
);
// Check that we don't fall back to DNS
await new TRRDNSListener("delay3.com", "1.2.3.4");
});
add_task(async function delayed_ipv4_answer_and_ipv6_error() {
// A comes back with delay.
// AAAA EDNS_ERROR comes immediately
await trrServer.registerDoHAnswers(
"delay4.com",
"A",
[
{
name: "delay4.com",
ttl: 55,
type: "A",
flush: false,
data: "1.2.3.4",
},
],
[],
200 // delay
);
await trrServer.registerDoHAnswers(
"delay4.com",
"AAAA",
[],
[
{
name: ".",
type: "OPT",
class: "IN",
options: [
{
code: "EDNS_ERROR",
extended_error: 17, // Filtered
text: "Filtered",
},
],
},
]
);
// Check that we don't fall back to DNS
await new TRRDNSListener("delay4.com", "1.2.3.4");
});

View File

@@ -451,9 +451,5 @@ skip-if = asan || tsan || os == 'win' || os =='android'
skip-if = asan || tsan || os == 'win' || os =='android' skip-if = asan || tsan || os == 'win' || os =='android'
[test_use_httpssvc.js] [test_use_httpssvc.js]
skip-if = os == "android" skip-if = os == "android"
[test_trr_additional_section.js]
skip-if = os == "android"
[test_trr_extended_error.js]
skip-if = os == "android"
[test_httpssvc_iphint.js] [test_httpssvc_iphint.js]
skip-if = os == "android" skip-if = os == "android"

View File

@@ -729,15 +729,6 @@ roption.encode = function (option, buf, offset) {
offset += 2 offset += 2
} }
break break
case 15: // EDNS_ERROR
const text = option.text || "";
buf.writeUInt16BE(text.length + 2, offset)
offset += 2;
buf.writeUInt16BE(option.extended_error, offset)
offset += 2;
buf.write(text, offset);
offset += option.text.length;
break;
default: default:
throw new Error(`Unknown roption code: ${option.code}`) throw new Error(`Unknown roption code: ${option.code}`)
} }
@@ -806,8 +797,6 @@ roption.encodingLength = function (option) {
return option.length + 4 return option.length + 4
case 14: // KEY-TAG case 14: // KEY-TAG
return 4 + (option.tags.length * 2) return 4 + (option.tags.length * 2)
case 15: // EDNS_ERROR
return 4 + 2 + option.text.length
} }
throw new Error(`Unknown roption code: ${option.code}`) throw new Error(`Unknown roption code: ${option.code}`)
} }

View File

@@ -17,7 +17,6 @@ exports.toString = function (type) {
case 12: return 'PADDING' case 12: return 'PADDING'
case 13: return 'CHAIN' case 13: return 'CHAIN'
case 14: return 'KEY_TAG' case 14: return 'KEY_TAG'
case 15: return 'EDNS_ERROR'
case 26946: return 'DEVICEID' case 26946: return 'DEVICEID'
} }
if (type < 0) { if (type < 0) {
@@ -49,7 +48,6 @@ exports.toCode = function (name) {
case 'PADDING': return 12 case 'PADDING': return 12
case 'CHAIN': return 13 case 'CHAIN': return 13
case 'KEY_TAG': return 14 case 'KEY_TAG': return 14
case 'EDNS_ERROR': return 15
case 'DEVICEID': return 26946 case 'DEVICEID': return 26946
case 'OPTION_65535': return 65535 case 'OPTION_65535': return 65535
} }

View File

@@ -382,10 +382,6 @@ with modules["NETWORK"]:
# speak to a proxy server, then it will generate this error if the proxy # speak to a proxy server, then it will generate this error if the proxy
# hostname cannot be resolved. # hostname cannot be resolved.
errors["NS_ERROR_UNKNOWN_PROXY_HOST"] = FAILURE(42) errors["NS_ERROR_UNKNOWN_PROXY_HOST"] = FAILURE(42)
# This DNS error will occur when the resolver uses the Extended DNS Error
# option to indicate an error code for which we should not fall back to the
# default DNS resolver. This means the DNS failure is definitive.
errors["NS_ERROR_DEFINITIVE_UNKNOWN_HOST"] = FAILURE(43)
# Socket specific error codes: # Socket specific error codes: