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:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:");
|
||||||
|
|||||||
@@ -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)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
@@ -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");
|
|
||||||
});
|
|
||||||
@@ -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"
|
||||||
|
|||||||
@@ -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}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user