Bug 807678: Don't proliferate NSPR DNS types beyond the host resolver itself. Make it possible to easily hook up other host resolvers. r=sworkman
authorJosh Aas <joshmoz@gmail.com>
Thu, 20 Dec 2012 14:47:07 -0500
changeset 116700 ec4e88c2c77a1d45b7878d72177daa0daea31fcb
parent 116699 73ce12dc950b5e4965c04f7ae3f480df1a60f6f5
child 116701 8cbe2966ec8a75a0b4cb2975edd9034fe1e6ded5
push idunknown
push userunknown
push dateunknown
reviewerssworkman
bugs807678
milestone20.0a1
Bug 807678: Don't proliferate NSPR DNS types beyond the host resolver itself. Make it possible to easily hook up other host resolvers. r=sworkman
netwerk/base/public/nsINetAddr.idl
netwerk/base/public/nsISocketTransport.idl
netwerk/base/src/ProxyAutoConfig.cpp
netwerk/base/src/ProxyAutoConfig.h
netwerk/base/src/nsNetAddr.cpp
netwerk/base/src/nsNetAddr.h
netwerk/base/src/nsServerSocket.cpp
netwerk/base/src/nsSocketTransport2.cpp
netwerk/base/src/nsSocketTransport2.h
netwerk/dns/DNS.cpp
netwerk/dns/DNS.h
netwerk/dns/Makefile.in
netwerk/dns/nsDNSService2.cpp
netwerk/dns/nsHostResolver.cpp
netwerk/dns/nsHostResolver.h
netwerk/dns/nsIDNSRecord.idl
netwerk/ipc/NeckoMessageUtils.h
netwerk/protocol/ftp/nsFtpConnectionThread.cpp
netwerk/protocol/ftp/nsFtpConnectionThread.h
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
netwerk/protocol/http/PHttpChannel.ipdl
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/socket/nsISOCKSSocketInfo.idl
netwerk/socket/nsSOCKSIOLayer.cpp
--- a/netwerk/base/public/nsINetAddr.idl
+++ b/netwerk/base/public/nsINetAddr.idl
@@ -1,37 +1,35 @@
 /* vim: et ts=4 sw=4 tw=80 
  */
 /* 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/. */
 
 #include "nsISupports.idl"
 
-native PRNetAddr(union PRNetAddr);
-
 /**
  * nsINetAddr
  *
- * This interface represents a (native) PRNetAddr struct in a readonly
+ * This interface represents a native NetAddr struct in a readonly
  * interface.
  */
 [scriptable, uuid(c407ab6c-c3ca-4cb2-a99b-a7dfbb88af33)]
 interface nsINetAddr : nsISupports
 {
     /**
      * @return the address family of the network address, which corresponds to
      * one of the FAMILY_ constants.
      */
     readonly attribute unsigned short family;
 
     /**
      * @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
-     * PR_NetAddrToString.
+     * mozilla::net::NetAddrToString.
      *
      * Note: Paths for FAMILY_LOCAL may have length limitations which are
      * implementation dependent and not documented as part of this interface.
      */
     readonly attribute AUTF8String address;
 
     /**
      * @return the port number for a FAMILY_INET or FAMILY_INET6 address.
@@ -56,14 +54,14 @@ interface nsINetAddr : nsISupports
      * @see http://tools.ietf.org/html/rfc4007
      *
      * @throws NS_ERROR_NOT_AVAILABLE if the address family is not FAMILY_INET6
      */
     readonly attribute unsigned long scope;
 
     /**
      * Network address families. These correspond to all the network address
-     * families supported by the PRNetAddr struct.
+     * families supported by the NetAddr struct.
      */
     const unsigned long FAMILY_INET = 1;
     const unsigned long FAMILY_INET6 = 2;
     const unsigned long FAMILY_LOCAL = 3;
 };
--- a/netwerk/base/public/nsISocketTransport.idl
+++ b/netwerk/base/public/nsISocketTransport.idl
@@ -3,52 +3,55 @@
  * 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/. */
 
 #include "nsITransport.idl"
 #include "nsINetAddr.idl"
 
 interface nsIInterfaceRequestor;
 
-native PRNetAddr(union PRNetAddr);
+%{ C++
+#include "mozilla/net/DNS.h"
+%}
+native NetAddr(mozilla::net::NetAddr);
 
 /**
  * nsISocketTransport
  *
  * NOTE: Connection setup is triggered by opening an input or output stream,
  * it does not start on its own. Completion of the connection setup is
  * indicated by a STATUS_CONNECTED_TO notification to the event sink (if set).
  *
  * NOTE: This is a free-threaded interface, meaning that the methods on
  * this interface may be called from any thread.
  */
-[scriptable, uuid(91ca3523-fc52-4dea-b167-ef8f56473dde)]
+[scriptable, uuid(A8318027-0DDC-4E60-A89B-D81AFE3B5020)]
 interface nsISocketTransport : nsITransport 
 {
     /**
      * Get the host for the underlying socket connection.
      */
     readonly attribute AUTF8String host;
 
     /**
      * Get the port for the underlying socket connection.
      */
     readonly attribute long port;
 
     /** 
      * Returns the IP address of the socket connection peer. This
      * attribute is defined only once a connection has been established.
      */
-    [noscript] PRNetAddr getPeerAddr();
+    [noscript] NetAddr getPeerAddr();
 
     /** 
      * Returns the IP address of the initiating end. This attribute
      * is defined only once a connection has been established.
      */
-    [noscript] PRNetAddr getSelfAddr();
+    [noscript] NetAddr getSelfAddr();
 
     /** 
      * Returns a scriptable version of getPeerAddr. This attribute is defined
      * only once a connection has been established.
      */
     nsINetAddr getScriptablePeerAddr();
 
     /** 
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -10,16 +10,17 @@
 #include "nsIDNSRecord.h"
 #include "nsIDNSService.h"
 #include "nsNetUtil.h"
 #include "nsThreadUtils.h"
 #include "nsIConsoleService.h"
 #include "nsJSUtils.h"
 #include "prnetdb.h"
 #include "nsITimer.h"
+#include "mozilla/net/DNS.h"
 
 namespace mozilla {
 namespace net {
 
 // These are some global helper symbols the PAC format requires that we provide that
 // are initialized as part of the global javascript context used for PAC evaluations.
 // Additionally dnsResolve(host) and myIpAddress() are supplied in the same context
 // but are implemented as c++ helpers. alert(msg) is similarly defined.
@@ -308,30 +309,30 @@ PACErrorReporter(JSContext *cx, const ch
   formattedMessage += report->uclinebuf;
   formattedMessage += NS_LITERAL_STRING("]");
   PACLogToConsole(formattedMessage);
 }
 
 // timeout of 0 means the normal necko timeout strategy, otherwise the dns request
 // will be canceled after aTimeout milliseconds
 static
-JSBool PACResolve(const nsCString &aHostName, PRNetAddr *aNetAddr,
+JSBool PACResolve(const nsCString &aHostName, NetAddr *aNetAddr,
                   unsigned int aTimeout)
 {
   if (!sRunning) {
     NS_WARNING("PACResolve without a running ProxyAutoConfig object");
     return false;
   }
 
   return sRunning->ResolveAddress(aHostName, aNetAddr, aTimeout);
 }
 
 bool
 ProxyAutoConfig::ResolveAddress(const nsCString &aHostName,
-                                PRNetAddr *aNetAddr,
+                                NetAddr *aNetAddr,
                                 unsigned int aTimeout)
 {
   nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
   if (!dns)
     return false;
 
   nsRefPtr<PACResolver> helper = new PACResolver();
 
@@ -361,22 +362,22 @@ ProxyAutoConfig::ResolveAddress(const ns
   return true;
 }
 
 static
 bool PACResolveToString(const nsCString &aHostName,
                         nsCString &aDottedDecimal,
                         unsigned int aTimeout)
 {
-  PRNetAddr netAddr;
+  NetAddr netAddr;
   if (!PACResolve(aHostName, &netAddr, aTimeout))
     return false;
 
   char dottedDecimal[128];
-  if (PR_NetAddrToString(&netAddr, dottedDecimal, sizeof(dottedDecimal)) != PR_SUCCESS)
+  if (!NetAddrToString(&netAddr, dottedDecimal, sizeof(dottedDecimal)))
     return false;
 
   aDottedDecimal.Assign(dottedDecimal);
   return true;
 }
 
 // dnsResolve(host) javascript implementation
 static
@@ -681,24 +682,26 @@ ProxyAutoConfig::Shutdown()
     return;
 
   mShutdown = true;
   delete mJSRuntime;
   mJSRuntime = nullptr;
 }
 
 bool
-ProxyAutoConfig::SrcAddress(const PRNetAddr *remoteAddress, nsCString &localAddress)
+ProxyAutoConfig::SrcAddress(const NetAddr *remoteAddress, nsCString &localAddress)
 {
   PRFileDesc *fd;
   fd = PR_OpenUDPSocket(remoteAddress->raw.family);
   if (!fd)
     return false;
 
-  if (PR_Connect(fd, remoteAddress, 0) != PR_SUCCESS) {
+  PRNetAddr prRemoteAddress;
+  NetAddrToPRNetAddr(remoteAddress, &prRemoteAddress);
+  if (PR_Connect(fd, &prRemoteAddress, 0) != PR_SUCCESS) {
     PR_Close(fd);
     return false;
   }
 
   PRNetAddr localName;
   if (PR_GetSockName(fd, &localName) != PR_SUCCESS) {
     PR_Close(fd);
     return false;
@@ -719,17 +722,17 @@ ProxyAutoConfig::SrcAddress(const PRNetA
 // to the result. If that all works, the local IP address of the socket is
 // returned to the javascript caller and true is returned from this function.
 // otherwise false is returned.
 bool
 ProxyAutoConfig::MyIPAddressTryHost(const nsCString &hostName,
                                     unsigned int timeout,
                                     jsval *vp)
 {
-  PRNetAddr remoteAddress;
+  NetAddr remoteAddress;
   nsAutoCString localDottedDecimal;
   JSContext *cx = mJSRuntime->Context();
 
   if (PACResolve(hostName, &remoteAddress, timeout) &&
       SrcAddress(&remoteAddress, localDottedDecimal)) {
     JSString *dottedDecimalString =
       JS_NewStringCopyZ(cx, localDottedDecimal.get());
     JS_SET_RVAL(cx, vp, STRING_TO_JSVAL(dottedDecimalString));
--- a/netwerk/base/src/ProxyAutoConfig.h
+++ b/netwerk/base/src/ProxyAutoConfig.h
@@ -7,16 +7,17 @@
 #ifndef ProxyAutoConfig_h__
 #define ProxyAutoConfig_h__
 
 #include "nsString.h"
 #include "jsapi.h"
 #include "prio.h"
 #include "nsITimer.h"
 #include "nsAutoPtr.h"
+#include "mozilla/net/DNS.h"
 
 namespace mozilla { namespace net {
 
 class JSRuntimeWrapper;
 
 // The ProxyAutoConfig class is meant to be created and run on a
 // non main thread. It synchronously resolves PAC files by blocking that
 // thread and running nested event loops. GetProxyForURI is not re-entrant.
@@ -33,17 +34,17 @@ public:
   ~ProxyAutoConfig();
 
   nsresult Init(const nsCString &aPACURI,
                 const nsCString &aPACScript);
   void     Shutdown();
   void     GC();
   bool     MyIPAddress(jsval *vp);
   bool     ResolveAddress(const nsCString &aHostName,
-                          PRNetAddr *aNetAddr, unsigned int aTimeout);
+                          NetAddr *aNetAddr, unsigned int aTimeout);
 
   /**
    * Get the proxy string for the specified URI.  The proxy string is
    * given by the following:
    *
    *   result      = proxy-spec *( proxy-sep proxy-spec )
    *   proxy-spec  = direct-type | proxy-type LWS proxy-host [":" proxy-port]
    *   direct-type = "DIRECT"
@@ -79,17 +80,17 @@ public:
                           nsACString &result);
 
 private:
   const static unsigned int kTimeout = 1000; // ms to allow for myipaddress dns queries
 
   // used to compile the PAC file and setup the execution context
   nsresult SetupJS();
 
-  bool SrcAddress(const PRNetAddr *remoteAddress, nsCString &localAddress);
+  bool SrcAddress(const NetAddr *remoteAddress, nsCString &localAddress);
   bool MyIPAddressTryHost(const nsCString &hostName, unsigned int timeout,
                           jsval *vp);
 
   JSRuntimeWrapper *mJSRuntime;
   bool              mJSNeedsSetup;
   bool              mShutdown;
   nsCString         mPACScript;
   nsCString         mPACURI;
--- a/netwerk/base/src/nsNetAddr.cpp
+++ b/netwerk/base/src/nsNetAddr.cpp
@@ -1,123 +1,132 @@
 /* vim: et ts=2 sw=2 tw=80 
  */
 /* 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/. */
 
 #include "nsNetAddr.h"
 #include "nsString.h"
+#include "prnetdb.h"
 
-#include "prnetdb.h"
+using namespace mozilla::net;
 
 NS_IMPL_ISUPPORTS1(nsNetAddr, nsINetAddr)
 
 /* Makes a copy of |addr| */
-nsNetAddr::nsNetAddr(PRNetAddr* addr)
+nsNetAddr::nsNetAddr(NetAddr* addr)
 {
   NS_ASSERTION(addr, "null addr");
   mAddr = *addr;
 }
 
 /* readonly attribute unsigned short family; */
 NS_IMETHODIMP nsNetAddr::GetFamily(uint16_t *aFamily)
 {
   switch(mAddr.raw.family) {
-  case PR_AF_INET: 
+  case AF_INET:
     *aFamily = nsINetAddr::FAMILY_INET;
     break;
-  case PR_AF_INET6:
+  case AF_INET6:
     *aFamily = nsINetAddr::FAMILY_INET6;
     break;
-  case PR_AF_LOCAL:
+#if defined(XP_UNIX) || defined(XP_OS2)
+  case AF_LOCAL:
     *aFamily = nsINetAddr::FAMILY_LOCAL;
     break;
+#endif
   default:
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 /* readonly attribute AUTF8String address; */
 NS_IMETHODIMP nsNetAddr::GetAddress(nsACString & aAddress)
 {
   switch(mAddr.raw.family) {
   /* PR_NetAddrToString can handle INET and INET6, but not LOCAL. */
-  case PR_AF_INET: 
-    aAddress.SetCapacity(16);
-    PR_NetAddrToString(&mAddr, aAddress.BeginWriting(), 16);
+  case AF_INET:
+    aAddress.SetCapacity(kIPv4CStrBufSize);
+    NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv4CStrBufSize);
     aAddress.SetLength(strlen(aAddress.BeginReading()));
     break;
-  case PR_AF_INET6:
-    aAddress.SetCapacity(46);
-    PR_NetAddrToString(&mAddr, aAddress.BeginWriting(), 46);
+  case AF_INET6:
+    aAddress.SetCapacity(kIPv6CStrBufSize);
+    NetAddrToString(&mAddr, aAddress.BeginWriting(), kIPv6CStrBufSize);
     aAddress.SetLength(strlen(aAddress.BeginReading()));
     break;
 #if defined(XP_UNIX) || defined(XP_OS2)
-  case PR_AF_LOCAL:
+  case AF_LOCAL:
     aAddress.Assign(mAddr.local.path);
     break;
 #endif
   // PR_AF_LOCAL falls through to default when not XP_UNIX || XP_OS2
   default:
     return NS_ERROR_UNEXPECTED;
   }
   
   return NS_OK;
 }
 
 /* readonly attribute unsigned short port; */
 NS_IMETHODIMP nsNetAddr::GetPort(uint16_t *aPort)
 {
   switch(mAddr.raw.family) {
-  case PR_AF_INET: 
-    *aPort = PR_ntohs(mAddr.inet.port);
+  case AF_INET:
+    *aPort = ntohs(mAddr.inet.port);
     break;
-  case PR_AF_INET6:
-    *aPort = PR_ntohs(mAddr.ipv6.port);
+  case AF_INET6:
+    *aPort = ntohs(mAddr.inet6.port);
     break;
-  case PR_AF_LOCAL:
+#if defined(XP_UNIX) || defined(XP_OS2)
+  case AF_LOCAL:
     // There is no port number for local / connections.
     return NS_ERROR_NOT_AVAILABLE;
+#endif
   default:
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 /* readonly attribute unsigned long flow; */
 NS_IMETHODIMP nsNetAddr::GetFlow(uint32_t *aFlow)
 {
   switch(mAddr.raw.family) {
-  case PR_AF_INET6:
-    *aFlow = PR_ntohl(mAddr.ipv6.flowinfo);
+  case AF_INET6:
+    *aFlow = ntohl(mAddr.inet6.flowinfo);
     break;
-  case PR_AF_INET: 
-  case PR_AF_LOCAL:
+  case AF_INET:
+#if defined(XP_UNIX) || defined(XP_OS2)
+  case AF_LOCAL:
+#endif
     // only for IPv6
     return NS_ERROR_NOT_AVAILABLE;
   default:
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
 
 /* readonly attribute unsigned long scope; */
 NS_IMETHODIMP nsNetAddr::GetScope(uint32_t *aScope)
 {
   switch(mAddr.raw.family) {
-  case PR_AF_INET6:
-    *aScope = PR_ntohl(mAddr.ipv6.scope_id);
+  case AF_INET6:
+    *aScope = ntohl(mAddr.inet6.scope_id);
     break;
-  case PR_AF_INET: 
-  case PR_AF_LOCAL:
+  case AF_INET:
+#if defined(XP_UNIX) || defined(XP_OS2)
+  case AF_LOCAL:
+#endif
     // only for IPv6
     return NS_ERROR_NOT_AVAILABLE;
   default:
     return NS_ERROR_UNEXPECTED;
   }
 
   return NS_OK;
 }
--- a/netwerk/base/src/nsNetAddr.h
+++ b/netwerk/base/src/nsNetAddr.h
@@ -3,27 +3,27 @@
 /* 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/. */
 
 #ifndef nsNetAddr_h__
 #define nsNetAddr_h__
 
 #include "nsINetAddr.h"
-#include "prio.h"
+#include "mozilla/net/DNS.h"
 #include "mozilla/Attributes.h"
 
 class nsNetAddr MOZ_FINAL : public nsINetAddr
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSINETADDR
 
-  nsNetAddr(PRNetAddr* addr);
+  nsNetAddr(mozilla::net::NetAddr* addr);
 
 private:
-  PRNetAddr mAddr;
+  mozilla::net::NetAddr mAddr;
 
 protected:
   /* additional members */
 };
 
 #endif // !nsNetAddr_h__
--- a/netwerk/base/src/nsServerSocket.cpp
+++ b/netwerk/base/src/nsServerSocket.cpp
@@ -8,18 +8,20 @@
 #include "nsServerSocket.h"
 #include "nsProxyRelease.h"
 #include "nsAutoPtr.h"
 #include "nsError.h"
 #include "nsNetCID.h"
 #include "prnetdb.h"
 #include "prio.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/net/DNS.h"
 
 using namespace mozilla;
+using namespace mozilla::net;
 
 static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
 
 //-----------------------------------------------------------------------------
 
 typedef void (nsServerSocket:: *nsServerSocketFunc)(void);
 
 static nsresult
@@ -162,19 +164,21 @@ nsServerSocket::OnSocketReady(PRFileDesc
   if (outFlags & (PR_POLL_ERR | PR_POLL_HUP | PR_POLL_NVAL))
   {
     NS_WARNING("error polling on listening socket");
     mCondition = NS_ERROR_UNEXPECTED;
     return;
   }
 
   PRFileDesc *clientFD;
-  PRNetAddr clientAddr;
+  PRNetAddr prClientAddr;
+  NetAddr clientAddr;
 
-  clientFD = PR_Accept(mFD, &clientAddr, PR_INTERVAL_NO_WAIT);
+  clientFD = PR_Accept(mFD, &prClientAddr, PR_INTERVAL_NO_WAIT);
+  PRNetAddrToNetAddr(&prClientAddr, &clientAddr);
   if (!clientFD)
   {
     NS_WARNING("PR_Accept failed");
     mCondition = NS_ERROR_UNEXPECTED;
   }
   else
   {
     nsRefPtr<nsSocketTransport> trans = new nsSocketTransport;
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -34,16 +34,17 @@
 #include "nsIProgrammingLanguage.h"
 #include "nsIClassInfoImpl.h"
 
 #if defined(XP_WIN) || defined(MOZ_PLATFORM_MAEMO)
 #include "nsNativeConnectionHelper.h"
 #endif
 
 using namespace mozilla;
+using namespace mozilla::net;
 
 //-----------------------------------------------------------------------------
 
 static NS_DEFINE_CID(kSocketProviderServiceCID, NS_SOCKETPROVIDERSERVICE_CID);
 static NS_DEFINE_CID(kDNSServiceCID, NS_DNSSERVICE_CID);
 
 //-----------------------------------------------------------------------------
 
@@ -801,32 +802,32 @@ nsSocketTransport::Init(const char **typ
             }
         }
     }
 
     return NS_OK;
 }
 
 nsresult
-nsSocketTransport::InitWithConnectedSocket(PRFileDesc *fd, const PRNetAddr *addr)
+nsSocketTransport::InitWithConnectedSocket(PRFileDesc *fd, const NetAddr *addr)
 {
     NS_ASSERTION(!mFD, "already initialized");
 
-    char buf[64];
-    PR_NetAddrToString(addr, buf, sizeof(buf));
+    char buf[kIPv6CStrBufSize];
+    NetAddrToString(addr, buf, sizeof(buf));
     mHost.Assign(buf);
 
     uint16_t port;
-    if (addr->raw.family == PR_AF_INET)
+    if (addr->raw.family == AF_INET)
         port = addr->inet.port;
     else
-        port = addr->ipv6.port;
-    mPort = PR_ntohs(port);
+        port = addr->inet6.port;
+    mPort = ntohs(port);
 
-    memcpy(&mNetAddr, addr, sizeof(PRNetAddr));
+    memcpy(&mNetAddr, addr, sizeof(NetAddr));
 
     mPollFlags = (PR_POLL_READ | PR_POLL_WRITE | PR_POLL_EXCEPT);
     mPollTimeout = mTimeouts[TIMEOUT_READ_WRITE];
     mState = STATE_TRANSFERRING;
     mNetAddrIsSet = true;
 
     mFD = fd;
     mFDref = 1;
@@ -902,17 +903,19 @@ nsSocketTransport::ResolveHost()
             // Name resolution is done on the server side.  Just pretend
             // client resolution is complete, this will get picked up later.
             // since we don't need to do DNS now, we bypass the resolving
             // step by initializing mNetAddr to an empty address, but we
             // must keep the port. The SOCKS IO layer will use the hostname
             // we send it when it's created, rather than the empty address
             // we send with the connect call.
             mState = STATE_RESOLVING;
-            PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, SocketPort(), &mNetAddr);
+            mNetAddr.raw.family = AF_INET;
+            mNetAddr.inet.port = htons(SocketPort());
+            mNetAddr.inet.ip = htonl(INADDR_ANY);
             return PostEvent(MSG_DNS_LOOKUP_COMPLETE, NS_OK, nullptr);
         }
     }
 
     nsCOMPtr<nsIDNSService> dns = do_GetService(kDNSServiceCID, &rv);
     if (NS_FAILED(rv)) return rv;
 
     mResolving = true;
@@ -1047,17 +1050,17 @@ nsSocketTransport::BuildSocket(PRFileDes
 nsresult
 nsSocketTransport::InitiateSocket()
 {
     SOCKET_LOG(("nsSocketTransport::InitiateSocket [this=%x]\n", this));
 
     nsresult rv;
 
     if (gIOService->IsOffline() &&
-        !PR_IsNetAddrType(&mNetAddr, PR_IpAddrLoopback))
+        !IsLoopBackAddress(&mNetAddr))
         return NS_ERROR_OFFLINE;
 
     //
     // find out if it is going to be ok to attach another socket to the STS.
     // if not then we have to wait for the STS to tell us that it is ok.
     // the notification is asynchronous, which means that when we could be
     // in a race to call AttachSocket once notified.  for this reason, when
     // we get notified, we just re-enter this function.  as a result, we are
@@ -1153,26 +1156,28 @@ nsSocketTransport::InitiateSocket()
 
     SOCKET_LOG(("  advancing to STATE_CONNECTING\n"));
     mState = STATE_CONNECTING;
     mPollTimeout = mTimeouts[TIMEOUT_CONNECT];
     SendStatus(NS_NET_STATUS_CONNECTING_TO);
 
 #if defined(PR_LOGGING)
     if (SOCKET_LOG_ENABLED()) {
-        char buf[64];
-        PR_NetAddrToString(&mNetAddr, buf, sizeof(buf));
+        char buf[kIPv6CStrBufSize];
+        NetAddrToString(&mNetAddr, buf, sizeof(buf));
         SOCKET_LOG(("  trying address: %s\n", buf));
     }
 #endif
 
     // 
     // Initiate the connect() to the host...  
     //
-    status = PR_Connect(fd, &mNetAddr, NS_SOCKET_CONNECT_TIMEOUT);
+    PRNetAddr prAddr;
+    NetAddrToPRNetAddr(&mNetAddr, &prAddr);
+    status = PR_Connect(fd, &prAddr, NS_SOCKET_CONNECT_TIMEOUT);
     if (status == PR_SUCCESS) {
         // 
         // we are connected!
         //
         OnSocketConnected();
     }
     else {
         PRErrorCode code = PR_GetError();
@@ -1674,17 +1679,17 @@ nsSocketTransport::OnSocketDetached(PRFi
     }
 }
 
 void
 nsSocketTransport::IsLocal(bool *aIsLocal)
 {
     {
         MutexAutoLock lock(mLock);
-        *aIsLocal = PR_IsNetAddrType(&mNetAddr, PR_IpAddrLoopback);
+        *aIsLocal = IsLoopBackAddress(&mNetAddr);
     }
 }
 
 //-----------------------------------------------------------------------------
 // xpcom api
 
 NS_IMPL_THREADSAFE_ISUPPORTS4(nsSocketTransport,
                               nsISocketTransport,
@@ -1895,81 +1900,84 @@ nsSocketTransport::GetHost(nsACString &h
 NS_IMETHODIMP
 nsSocketTransport::GetPort(int32_t *port)
 {
     *port = (int32_t) SocketPort();
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSocketTransport::GetPeerAddr(PRNetAddr *addr)
+nsSocketTransport::GetPeerAddr(NetAddr *addr)
 {
     // once we are in the connected state, mNetAddr will not change.
     // so if we can verify that we are in the connected state, then
     // we can freely access mNetAddr from any thread without being
     // inside a critical section.
 
     if (!mNetAddrIsSet) {
         SOCKET_LOG(("nsSocketTransport::GetPeerAddr [this=%p state=%d] "
                     "NOT_AVAILABLE because not yet connected.", this, mState));
         return NS_ERROR_NOT_AVAILABLE;
     }
 
-    memcpy(addr, &mNetAddr, sizeof(mNetAddr));
+    memcpy(addr, &mNetAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSocketTransport::GetSelfAddr(PRNetAddr *addr)
+nsSocketTransport::GetSelfAddr(NetAddr *addr)
 {
     // we must not call any PR methods on our file descriptor
     // while holding mLock since those methods might re-enter
     // socket transport code.
 
     PRFileDesc *fd;
     {
         MutexAutoLock lock(mLock);
         fd = GetFD_Locked();
     }
 
-    if (!fd)
+    if (!fd) {
         return NS_ERROR_NOT_CONNECTED;
+    }
 
+    PRNetAddr prAddr;
     nsresult rv =
-        (PR_GetSockName(fd, addr) == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
+        (PR_GetSockName(fd, &prAddr) == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
+    PRNetAddrToNetAddr(&prAddr, addr);
 
     {
         MutexAutoLock lock(mLock);
         ReleaseFD_Locked(fd);
     }
 
     return rv;
 }
 
 /* nsINetAddr getScriptablePeerAddr (); */
 NS_IMETHODIMP
 nsSocketTransport::GetScriptablePeerAddr(nsINetAddr * *addr)
 {
-    PRNetAddr rawAddr;
+    NetAddr rawAddr;
 
     nsresult rv;
     rv = GetPeerAddr(&rawAddr);
     if (NS_FAILED(rv))
         return rv;
 
     NS_ADDREF(*addr = new nsNetAddr(&rawAddr));
 
     return NS_OK;
 }
 
 /* nsINetAddr getScriptableSelfAddr (); */
 NS_IMETHODIMP
 nsSocketTransport::GetScriptableSelfAddr(nsINetAddr * *addr)
 {
-    PRNetAddr rawAddr;
+    NetAddr rawAddr;
 
     nsresult rv;
     rv = GetSelfAddr(&rawAddr);
     if (NS_FAILED(rv))
         return rv;
 
     NS_ADDREF(*addr = new nsNetAddr(&rawAddr));
 
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -17,16 +17,17 @@
 #include "nsISocketTransport.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIAsyncOutputStream.h"
 #include "nsIDNSListener.h"
 #include "nsIDNSRecord.h"
 #include "nsICancelable.h"
 #include "nsIClassInfo.h"
+#include "mozilla/net/DNS.h"
 
 class nsSocketTransport;
 
 //-----------------------------------------------------------------------------
 
 // after this short interval, we will return to PR_Poll
 #define NS_SOCKET_CONNECT_TIMEOUT PR_MillisecondsToInterval(20)
 
@@ -116,17 +117,17 @@ public:
     // given type(s) to the given host or proxy.
     nsresult Init(const char **socketTypes, uint32_t typeCount,
                   const nsACString &host, uint16_t port,
                   nsIProxyInfo *proxyInfo);
 
     // this method instructs the socket transport to use an already connected
     // socket with the given address.
     nsresult InitWithConnectedSocket(PRFileDesc *socketFD,
-                                     const PRNetAddr *addr);
+                                     const mozilla::net::NetAddr *addr);
 
     // nsASocketHandler methods:
     void OnSocketReady(PRFileDesc *, int16_t outFlags); 
     void OnSocketDetached(PRFileDesc *);
     void IsLocal(bool *aIsLocal);
 
     // called when a socket event is handled
     void OnSocketEvent(uint32_t type, nsresult status, nsISupports *param);
@@ -194,17 +195,17 @@ private:
     // recursively or not.  this flag is not protected by any lock.
     bool mResolving;
 
     nsCOMPtr<nsICancelable> mDNSRequest;
     nsCOMPtr<nsIDNSRecord>  mDNSRecord;
 
     // mNetAddr is valid from GetPeerAddr() once we have
     // reached STATE_TRANSFERRING. It must not change after that.
-    PRNetAddr               mNetAddr;
+    mozilla::net::NetAddr   mNetAddr;
     bool                    mNetAddrIsSet;
 
     // socket methods (these can only be called on the socket thread):
 
     void     SendStatus(nsresult status);
     nsresult ResolveHost();
     nsresult BuildSocket(PRFileDesc *&, bool &, bool &); 
     nsresult InitiateSocket();
new file mode 100644
--- /dev/null
+++ b/netwerk/dns/DNS.cpp
@@ -0,0 +1,205 @@
+/* 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/. */
+
+#include "mozilla/net/DNS.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/mozalloc.h"
+#include <string.h>
+
+#ifdef XP_WIN
+#include "Ws2tcpip.h"
+#endif
+
+namespace mozilla {
+namespace net {
+
+const char *inet_ntop_internal(int af, const void *src, char *dst, socklen_t size)
+{
+#ifdef XP_WIN
+  if (af == AF_INET) {
+    struct sockaddr_in s;
+    memset(&s, 0, sizeof(s));
+    s.sin_family = AF_INET;
+    memcpy(&s.sin_addr, src, sizeof(struct in_addr));
+    int result = getnameinfo((struct sockaddr *)&s, sizeof(struct sockaddr_in),
+                             dst, size, nullptr, 0, NI_NUMERICHOST);
+    if (result == 0) {
+      return dst;
+    }
+  }
+  else if (af == AF_INET6) {
+    struct sockaddr_in6 s;
+    memset(&s, 0, sizeof(s));
+    s.sin6_family = AF_INET6;
+    memcpy(&s.sin6_addr, src, sizeof(struct in_addr6));
+    int result = getnameinfo((struct sockaddr *)&s, sizeof(struct sockaddr_in6),
+                             dst, size, nullptr, 0, NI_NUMERICHOST);
+    if (result == 0) {
+      return dst;
+    }
+  }
+  return nullptr;
+#else
+  return inet_ntop(af, src, dst, size);
+#endif
+}
+
+// Copies the contents of a PRNetAddr to a NetAddr.
+// Does not do a ptr safety check!
+void PRNetAddrToNetAddr(const PRNetAddr *prAddr, NetAddr *addr)
+{
+  if (prAddr->raw.family == PR_AF_INET) {
+    addr->inet.family = AF_INET;
+    addr->inet.port = prAddr->inet.port;
+    addr->inet.ip = prAddr->inet.ip;
+  }
+  else if (prAddr->raw.family == PR_AF_INET6) {
+    addr->inet6.family = AF_INET6;
+    addr->inet6.port = prAddr->ipv6.port;
+    addr->inet6.flowinfo = prAddr->ipv6.flowinfo;
+    memcpy(&addr->inet6.ip, &prAddr->ipv6.ip, sizeof(addr->inet6.ip.u8));
+    addr->inet6.scope_id = prAddr->ipv6.scope_id;
+  }
+#if defined(XP_UNIX) || defined(XP_OS2)
+  else if (prAddr->raw.family == PR_AF_LOCAL) {
+    addr->local.family = AF_LOCAL;
+    memcpy(addr->local.path, prAddr->local.path, sizeof(addr->local.path));
+  }
+#endif
+}
+
+// Copies the contents of a NetAddr to a PRNetAddr.
+// Does not do a ptr safety check!
+void NetAddrToPRNetAddr(const NetAddr *addr, PRNetAddr *prAddr)
+{
+  if (addr->raw.family == AF_INET) {
+    prAddr->inet.family = PR_AF_INET;
+    prAddr->inet.port = addr->inet.port;
+    prAddr->inet.ip = addr->inet.ip;
+  }
+  else if (addr->raw.family == AF_INET6) {
+    prAddr->ipv6.family = PR_AF_INET6;
+    prAddr->ipv6.port = addr->inet6.port;
+    prAddr->ipv6.flowinfo = addr->inet6.flowinfo;
+    memcpy(&prAddr->ipv6.ip, &addr->inet6.ip, sizeof(addr->inet6.ip.u8));
+    prAddr->ipv6.scope_id = addr->inet6.scope_id;
+  }
+#if defined(XP_UNIX) || defined(XP_OS2)
+  else if (addr->raw.family == AF_LOCAL) {
+    prAddr->local.family = PR_AF_LOCAL;
+    memcpy(prAddr->local.path, addr->local.path, sizeof(addr->local.path));
+  }
+#endif
+}
+
+bool NetAddrToString(const NetAddr *addr, char *buf, uint32_t bufSize)
+{
+  if (addr->raw.family == AF_INET) {
+    if (bufSize < INET_ADDRSTRLEN) {
+      return false;
+    }
+    struct in_addr nativeAddr = {};
+    nativeAddr.s_addr = addr->inet.ip;
+    return !!inet_ntop_internal(AF_INET, &nativeAddr, buf, bufSize);
+  }
+  else if (addr->raw.family == AF_INET6) {
+    if (bufSize < INET6_ADDRSTRLEN) {
+      return false;
+    }
+    struct in6_addr nativeAddr = {};
+    memcpy(&nativeAddr.s6_addr, &addr->inet6.ip, sizeof(addr->inet6.ip.u8));
+    return !!inet_ntop_internal(AF_INET6, &nativeAddr, buf, bufSize);
+  }
+#if defined(XP_UNIX) || defined(XP_OS2)
+  else if (addr->raw.family == AF_LOCAL) {
+    if (bufSize < sizeof(addr->local.path)) {
+      return false;
+    }
+    memcpy(buf, addr->local.path, bufSize);
+    return true;
+  }
+#endif
+  return false;
+}
+
+bool IsLoopBackAddress(const NetAddr *addr)
+{
+  if (addr->raw.family == AF_INET) {
+    return (addr->inet.ip == htonl(INADDR_LOOPBACK));
+  }
+  else if (addr->raw.family == AF_INET6) {
+    if (IPv6ADDR_IS_LOOPBACK(&addr->inet6.ip)) {
+      return true;
+    } else if (IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip) &&
+               IPv6ADDR_V4MAPPED_TO_IPADDR(&addr->inet6.ip) == htonl(INADDR_LOOPBACK)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool IsIPAddrAny(const NetAddr *addr)
+{
+  if (addr->raw.family == AF_INET) {
+    if (addr->inet.ip == htonl(INADDR_ANY)) {
+      return true;
+    }
+  }
+  else if (addr->raw.family == AF_INET6) {
+    if (IPv6ADDR_IS_UNSPECIFIED(&addr->inet6.ip)) {
+      return true;
+    } else if (IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip) &&
+               IPv6ADDR_V4MAPPED_TO_IPADDR(&addr->inet6.ip) == htonl(INADDR_ANY)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool IsIPAddrV4Mapped(const NetAddr *addr)
+{
+  if (addr->raw.family == AF_INET6) {
+    return IPv6ADDR_IS_V4MAPPED(&addr->inet6.ip);
+  }
+  return false;
+}
+
+NetAddrElement::NetAddrElement(const PRNetAddr *prNetAddr)
+{
+  PRNetAddrToNetAddr(prNetAddr, &mAddress);
+}
+
+NetAddrElement::~NetAddrElement()
+{
+}
+
+AddrInfo::AddrInfo(const char *host, const PRAddrInfo *prAddrInfo)
+{
+  size_t hostlen = strlen(host);
+  mHostName = static_cast<char*>(moz_xmalloc(hostlen + 1));
+  memcpy(mHostName, host, hostlen + 1);
+
+  PRNetAddr tmpAddr;
+  void *iter = nullptr;
+  do {
+    iter = PR_EnumerateAddrInfo(iter, prAddrInfo, 0, &tmpAddr);
+    if (iter) {
+      NetAddrElement *addrElement = new NetAddrElement(&tmpAddr);
+      mAddresses.insertBack(addrElement);
+    }
+  } while (iter);
+}
+
+AddrInfo::~AddrInfo()
+{
+  NetAddrElement *addrElement;
+  while ((addrElement = mAddresses.popLast())) {
+    delete addrElement;
+  }
+  free(mHostName);
+}
+
+} // namespace dns
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/netwerk/dns/DNS.h
@@ -0,0 +1,141 @@
+/* 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/. */
+
+#ifndef DNS_h_
+#define DNS_h_
+
+#include "nscore.h"
+#include "prio.h"
+#include "prnetdb.h"
+#include "mozilla/LinkedList.h"
+
+#if !defined(XP_WIN) && !defined(XP_OS2)
+#include <arpa/inet.h>
+#endif
+
+#ifdef XP_WIN
+#include "Winsock2.h"
+#endif
+
+#define IPv6ADDR_IS_LOOPBACK(a) \
+  (((a)->u32[0] == 0)     &&    \
+   ((a)->u32[1] == 0)     &&    \
+   ((a)->u32[2] == 0)     &&    \
+   ((a)->u8[12] == 0)     &&    \
+   ((a)->u8[13] == 0)     &&    \
+   ((a)->u8[14] == 0)     &&    \
+   ((a)->u8[15] == 0x1U))
+
+#define IPv6ADDR_IS_V4MAPPED(a) \
+  (((a)->u32[0] == 0)     &&    \
+   ((a)->u32[1] == 0)     &&    \
+   ((a)->u8[8] == 0)      &&    \
+   ((a)->u8[9] == 0)      &&    \
+   ((a)->u8[10] == 0xff)  &&    \
+   ((a)->u8[11] == 0xff))
+
+#define IPv6ADDR_V4MAPPED_TO_IPADDR(a) ((a)->u32[3])
+
+#define IPv6ADDR_IS_UNSPECIFIED(a) \
+  (((a)->u32[0] == 0)  &&          \
+   ((a)->u32[1] == 0)  &&          \
+   ((a)->u32[2] == 0)  &&          \
+   ((a)->u32[3] == 0))
+
+namespace mozilla {
+namespace net {
+
+// Required buffer size for text form of an IP address.
+// Includes space for null termination.
+const int kIPv4CStrBufSize = 16;
+const int kIPv6CStrBufSize = 46;
+
+// This was all created at a time in which we were using NSPR for host
+// resolution and we were propagating NSPR types like "PRAddrInfo" and
+// "PRNetAddr" all over Gecko. This made it hard to use another host
+// resolver -- we were locked into NSPR. The goal here is to get away
+// from that. We'll translate what we get from NSPR or any other host
+// resolution library into the types below and use them in Gecko.
+
+union IPv6Addr {
+  uint8_t  u8[16];
+  uint16_t u16[8];
+  uint32_t u32[4];
+  uint64_t u64[2];
+};
+
+// This struct is similar to operating system structs like "sockaddr", used for
+// things like "connect" and "getsockname". When tempted to cast or do dumb
+// copies of this struct to another struct, bear compiler-computed padding
+// in mind. The size of this struct, and the layout of the data in it, may
+// not be what you expect.
+union NetAddr {
+  struct {
+    uint16_t family;                /* address family (0x00ff maskable) */
+    char data[14];                  /* raw address data */
+  } raw;
+  struct {
+    uint16_t family;                /* address family (AF_INET) */
+    uint16_t port;                  /* port number */
+    uint32_t ip;                    /* The actual 32 bits of address */
+  } inet;
+  struct {
+    uint16_t family;                /* address family (AF_INET6) */
+    uint16_t port;                  /* port number */
+    uint32_t flowinfo;              /* routing information */
+    IPv6Addr ip;                    /* the actual 128 bits of address */
+    uint32_t scope_id;              /* set of interfaces for a scope */
+  } inet6;
+#if defined(XP_UNIX) || defined(XP_OS2)
+  struct {                          /* Unix domain socket address */
+    uint16_t family;                /* address family (AF_UNIX) */
+#ifdef XP_OS2
+    char path[108];                 /* null-terminated pathname */
+#else
+    char path[104];                 /* null-terminated pathname */
+#endif
+  } local;
+#endif
+};
+
+// This class wraps a NetAddr union to provide C++ linked list
+// capabilities and other methods. It is created from a PRNetAddr,
+// which is converted to a mozilla::dns::NetAddr.
+class NetAddrElement : public LinkedListElement<NetAddrElement> {
+public:
+  NetAddrElement(const PRNetAddr *prNetAddr);
+  ~NetAddrElement();
+
+  NetAddr mAddress;
+};
+    
+class AddrInfo {
+public:
+  AddrInfo(const char *host, const PRAddrInfo *prAddrInfo);
+  ~AddrInfo();
+
+  char *mHostName;
+  LinkedList<NetAddrElement> mAddresses;
+};
+
+// Copies the contents of a PRNetAddr to a NetAddr.
+// Does not do a ptr safety check!
+void PRNetAddrToNetAddr(const PRNetAddr *prAddr, NetAddr *addr);
+
+// Copies the contents of a NetAddr to a PRNetAddr.
+// Does not do a ptr safety check!
+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 IsIPAddrV4Mapped(const NetAddr *addr);
+
+} // namespace net
+} // namespace mozilla
+
+#endif // DNS_h_
--- a/netwerk/dns/Makefile.in
+++ b/netwerk/dns/Makefile.in
@@ -22,28 +22,35 @@ XPIDLSRCS = \
   nsIDNSRecord.idl \
   nsIDNSService.idl \
   nsIEffectiveTLDService.idl \
   nsIIDNService.idl \
   nsPIDNSService.idl \
   $(NULL)
 
 CPPSRCS = \
+  DNS.cpp \
   nsIDNService.cpp \
+  nsHostResolver.cpp \
   nsDNSService2.cpp \
-  nsHostResolver.cpp \
   nsEffectiveTLDService.cpp \
   $(NULL)
 
 CSRCS = \
   race.c \
   nameprep.c \
   punycode.c \
   $(NULL)
 
+EXPORTS_NAMESPACES = mozilla/net
+
+EXPORTS_mozilla/net = \
+  DNS.h \
+  $(null)
+
 # we don't want the shared lib, but we want to force the creation of a
 # static lib.
 FORCE_STATIC_LIB = 1
 
 # need to include etld_data.inc
 LOCAL_INCLUDES = \
   -I$(srcdir)/../base/src \
   -I. \
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -25,16 +25,17 @@
 #include "prio.h"
 #include "plstr.h"
 #include "nsIOService.h"
 #include "nsCharSeparatedTokenizer.h"
 
 #include "mozilla/Attributes.h"
 
 using namespace mozilla;
+using namespace mozilla::net;
 
 static const char kPrefDnsCacheEntries[]    = "network.dnsCacheEntries";
 static const char kPrefDnsCacheExpiration[] = "network.dnsCacheExpiration";
 static const char kPrefDnsCacheGrace[]      = "network.dnsCacheExpirationGracePeriod";
 static const char kPrefEnableIDN[]          = "network.enableIDN";
 static const char kPrefIPv4OnlyDomains[]    = "network.dns.ipv4OnlyDomains";
 static const char kPrefDisableIPv6[]        = "network.dns.disableIPv6";
 static const char kPrefDisablePrefetch[]    = "network.dns.disablePrefetch";
@@ -46,27 +47,24 @@ class nsDNSRecord : public nsIDNSRecord
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIDNSRECORD
 
     nsDNSRecord(nsHostRecord *hostRecord)
         : mHostRecord(hostRecord)
         , mIter(nullptr)
-        , mLastIter(nullptr)
         , mIterGenCnt(-1)
         , mDone(false) {}
 
 private:
     virtual ~nsDNSRecord() {}
 
     nsRefPtr<nsHostRecord>  mHostRecord;
-    void                   *mIter;       // enum ptr for PR_EnumerateAddrInfo
-    void                   *mLastIter;   // previous enum ptr, for use in
-                                         // getting addrinfo in ReportUnusable
+    NetAddrElement         *mIter;
     int                     mIterGenCnt; // the generation count of
                                          // mHostRecord->addr_info when we
                                          // start iterating
     bool                    mDone;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsDNSRecord, nsIDNSRecord)
 
@@ -78,157 +76,154 @@ nsDNSRecord::GetCanonicalName(nsACString
                    NS_ERROR_NOT_AVAILABLE);
 
     // if the record is for an IP address literal, then the canonical
     // host name is the IP address literal.
     const char *cname;
     {
         MutexAutoLock lock(mHostRecord->addr_info_lock);
         if (mHostRecord->addr_info)
-            cname = PR_GetCanonNameFromAddrInfo(mHostRecord->addr_info);
+            cname = mHostRecord->addr_info->mHostName;
         else
             cname = mHostRecord->host;
         result.Assign(cname);
     }
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsDNSRecord::GetNextAddr(uint16_t port, PRNetAddr *addr)
+nsDNSRecord::GetNextAddr(uint16_t port, NetAddr *addr)
 {
-    // not a programming error to poke the DNS record when it has no more
-    // entries.  just fail without any debug warnings.  this enables consumers
-    // to enumerate the DNS record without calling HasMore.
-    if (mDone)
+    if (mDone) {
         return NS_ERROR_NOT_AVAILABLE;
+    }
 
     mHostRecord->addr_info_lock.Lock();
-    bool startedFresh = !mIter;
-
     if (mHostRecord->addr_info) {
-        if (!mIter)
-            mIterGenCnt = mHostRecord->addr_info_gencnt;
-        else if (mIterGenCnt != mHostRecord->addr_info_gencnt) {
-            // mHostRecord->addr_info has changed, so mIter is invalid.
-            // Restart the iteration.  Alternatively, we could just fail.
+        if (mIterGenCnt != mHostRecord->addr_info_gencnt) {
+            // mHostRecord->addr_info has changed, restart the iteration.
             mIter = nullptr;
             mIterGenCnt = mHostRecord->addr_info_gencnt;
-            startedFresh = true;
         }
 
+        bool startedFresh = !mIter;
+
         do {
-            mLastIter = mIter;
-            mIter = PR_EnumerateAddrInfo(mIter, mHostRecord->addr_info,
-                                         port, addr);
+            if (!mIter) {
+                mIter = mHostRecord->addr_info->mAddresses.getFirst();
+            } else {
+                mIter = mIter->getNext();
+            }
         }
-        while (mIter && mHostRecord->Blacklisted(addr));
+        while (mIter && mHostRecord->Blacklisted(&mIter->mAddress));
 
-        if (startedFresh && !mIter) {
-            // if everything was blacklisted we want to reset the blacklist (and
+        if (!mIter && startedFresh) {
+            // If everything was blacklisted we want to reset the blacklist (and
             // likely relearn it) and return the first address. That is better
-            // than nothing
+            // than nothing.
             mHostRecord->ResetBlacklist();
-            mLastIter = nullptr;
-            mIter = PR_EnumerateAddrInfo(nullptr, mHostRecord->addr_info,
-                                         port, addr);
+            mIter = mHostRecord->addr_info->mAddresses.getFirst();
         }
-            
+
+        if (mIter) {
+            memcpy(addr, &mIter->mAddress, sizeof(NetAddr));
+        }
+
         mHostRecord->addr_info_lock.Unlock();
+
         if (!mIter) {
             mDone = true;
             return NS_ERROR_NOT_AVAILABLE;
         }
     }
     else {
         mHostRecord->addr_info_lock.Unlock();
+
         if (!mHostRecord->addr) {
             // Both mHostRecord->addr_info and mHostRecord->addr are null.
             // This can happen if mHostRecord->addr_info expired and the
             // attempt to reresolve it failed.
             return NS_ERROR_NOT_AVAILABLE;
         }
-        memcpy(addr, mHostRecord->addr, sizeof(PRNetAddr));
-        // set given port
-        port = PR_htons(port);
-        if (addr->raw.family == PR_AF_INET)
-            addr->inet.port = port;
-        else
-            addr->ipv6.port = port;
-        mDone = true; // no iterations
+        memcpy(addr, mHostRecord->addr, sizeof(NetAddr));
+        mDone = true;
     }
-        
-    return NS_OK; 
+
+    // set given port
+    port = htons(port);
+    if (addr->raw.family == AF_INET) {
+        addr->inet.port = port;
+    }
+    else if (addr->raw.family == AF_INET6) {
+        addr->inet6.port = port;
+    }
+
+    return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDNSRecord::GetNextAddrAsString(nsACString &result)
 {
-    PRNetAddr addr;
+    NetAddr addr;
     nsresult rv = GetNextAddr(0, &addr);
     if (NS_FAILED(rv)) return rv;
 
-    char buf[64];
-    if (PR_NetAddrToString(&addr, buf, sizeof(buf)) == PR_SUCCESS) {
+    char buf[kIPv6CStrBufSize];
+    if (NetAddrToString(&addr, buf, sizeof(buf))) {
         result.Assign(buf);
         return NS_OK;
     }
-    NS_ERROR("PR_NetAddrToString failed unexpectedly");
+    NS_ERROR("NetAddrToString failed unexpectedly");
     return NS_ERROR_FAILURE; // conversion failed for some reason
 }
 
 NS_IMETHODIMP
 nsDNSRecord::HasMore(bool *result)
 {
-    if (mDone)
+    if (mDone) {
         *result = false;
-    else {
-        // unfortunately, NSPR does not provide a way for us to determine if
-        // there is another address other than to simply get the next address.
-        void *iterCopy = mIter;
-        void *iterLastCopy = mLastIter;
-        PRNetAddr addr;
-        *result = NS_SUCCEEDED(GetNextAddr(0, &addr));
-        mIter = iterCopy; // backup iterator
-        mLastIter = iterLastCopy; // backup iterator
-        mDone = false;
+        return NS_OK;
     }
+
+    NetAddrElement *iterCopy = mIter;
+
+    NetAddr addr;
+    *result = NS_SUCCEEDED(GetNextAddr(0, &addr));
+
+    mIter = iterCopy;
+    mDone = false;
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDNSRecord::Rewind()
 {
     mIter = nullptr;
-    mLastIter = nullptr;
     mIterGenCnt = -1;
     mDone = false;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDNSRecord::ReportUnusable(uint16_t aPort)
 {
     // right now we don't use the port in the blacklist
 
-    mHostRecord->addr_info_lock.Lock();
+    MutexAutoLock lock(mHostRecord->addr_info_lock);
 
     // Check that we are using a real addr_info (as opposed to a single
     // constant address), and that the generation count is valid. Otherwise,
     // ignore the report.
 
     if (mHostRecord->addr_info &&
         mIterGenCnt == mHostRecord->addr_info_gencnt) {
-        PRNetAddr addr;
-        void *id = PR_EnumerateAddrInfo(mLastIter, mHostRecord->addr_info,
-                                        aPort, &addr);
-        if (id)
-            mHostRecord->ReportUnusable(&addr);
+        mHostRecord->ReportUnusable(&mIter->mAddress);
     }
-    
-    mHostRecord->addr_info_lock.Unlock();
+
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 
 class nsDNSAsyncRequest MOZ_FINAL : public nsResolveHostCallback
                                   , public nsICancelable
 {
--- a/netwerk/dns/nsHostResolver.cpp
+++ b/netwerk/dns/nsHostResolver.cpp
@@ -180,50 +180,50 @@ nsHostRecord::Create(const nsHostKey *ke
 
 nsHostRecord::~nsHostRecord()
 {
     if (addr)
         free(addr);
 }
 
 bool
-nsHostRecord::Blacklisted(PRNetAddr *aQuery)
+nsHostRecord::Blacklisted(NetAddr *aQuery)
 {
     // must call locked
     LOG(("Checking blacklist for host [%s], host record [%p].\n", host, this));
 
     // skip the string conversion for the common case of no blacklist
     if (!mBlacklistedItems.Length()) {
         return false;
     }
 
-    char buf[64];
-    if (PR_NetAddrToString(aQuery, buf, sizeof(buf)) != PR_SUCCESS) {
+    char buf[kIPv6CStrBufSize];
+    if (!NetAddrToString(aQuery, buf, sizeof(buf))) {
         return false;
     }
     nsDependentCString strQuery(buf);
 
     for (uint32_t i = 0; i < mBlacklistedItems.Length(); i++) {
         if (mBlacklistedItems.ElementAt(i).Equals(strQuery)) {
             LOG(("Address [%s] is blacklisted for host [%s].\n", buf, host));
             return true;
         }
     }
 
     return false;
 }
 
 void
-nsHostRecord::ReportUnusable(PRNetAddr *aAddress)
+nsHostRecord::ReportUnusable(NetAddr *aAddress)
 {
     // must call locked
     LOG(("Adding address to blacklist for host [%s], host record [%p].\n", host, this));
 
-    char buf[64];
-    if (PR_NetAddrToString(aAddress, buf, sizeof(buf)) == PR_SUCCESS) {
+    char buf[kIPv6CStrBufSize];
+    if (NetAddrToString(aAddress, buf, sizeof(buf))) {
         LOG(("Successfully adding address [%s] to blacklist for host [%s].\n", buf, host));
         mBlacklistedItems.AppendElement(nsCString(buf));
     }
 }
 
 void
 nsHostRecord::ResetBlacklist()
 {
@@ -270,31 +270,30 @@ HostDB_MoveEntry(PLDHashTable *table,
 
 static void
 HostDB_ClearEntry(PLDHashTable *table,
                   PLDHashEntryHdr *entry)
 {
     nsHostDBEnt *he = static_cast<nsHostDBEnt *>(entry);
     LOG(("Clearing cache db entry for host [%s].\n", he->rec->host));
 #if defined(DEBUG) && defined(PR_LOGGING)
-    if (!he->rec->addr_info) {
-        LOG(("No address info for host [%s].\n", he->rec->host));
-    } else {
-        int32_t now = (int32_t) NowInMinutes();
-        int32_t diff = (int32_t) he->rec->expiration - now;
-        LOG(("Record for [%s] expires in %d minute(s).\n", he->rec->host, diff));
-        void *iter = nullptr;
-        PRNetAddr addr;
-        char buf[64];
-        for (;;) {
-            iter = PR_EnumerateAddrInfo(iter, he->rec->addr_info, 0, &addr);
-            if (!iter)
-                break;
-            PR_NetAddrToString(&addr, buf, sizeof(buf));
-            LOG(("  [%s]\n", buf));
+    {
+        MutexAutoLock lock(he->rec->addr_info_lock);
+        if (!he->rec->addr_info) {
+            LOG(("No address info for host [%s].\n", he->rec->host));
+        } else {
+            int32_t now = (int32_t) NowInMinutes();
+            int32_t diff = (int32_t) he->rec->expiration - now;
+            LOG(("Record for [%s] expires in %d minute(s).\n", he->rec->host, diff));
+            NetAddrElement *addrElement;
+            char buf[kIPv6CStrBufSize];
+            while ((addrElement = he->rec->addr_info->mAddresses.popLast())) {
+                NetAddrToString(&addrElement->mAddress, buf, sizeof(buf));
+                LOG(("  [%s]\n", buf));
+            }
         }
     }
 #endif
     NS_RELEASE(he->rec);
 }
 
 static bool
 HostDB_InitEntry(PLDHashTable *table,
@@ -501,20 +500,20 @@ nsHostResolver::ResolveHost(const char  
     nsRefPtr<nsHostRecord> result;
     nsresult status = NS_OK, rv = NS_OK;
     {
         MutexAutoLock lock(mLock);
 
         if (mShutdown)
             rv = NS_ERROR_NOT_INITIALIZED;
         else {
+            // Used to try to parse to an IP address literal.
             PRNetAddr tempAddr;
-
-            // unfortunately, PR_StringToNetAddr does not properly initialize
-            // the output buffer in the case of IPv6 input.  see bug 223145.
+            // Unfortunately, PR_StringToNetAddr does not properly initialize
+            // the output buffer in the case of IPv6 input. See bug 223145.
             memset(&tempAddr, 0, sizeof(PRNetAddr));
             
             // check to see if there is already an entry for this |host|
             // in the hash table.  if so, then check to see if we can't
             // just reuse the lookup result.  otherwise, if there are
             // any pending callbacks, then add to pending callbacks queue,
             // and return.  otherwise, add ourselves as first pending
             // callback, and proceed to do the lookup.
@@ -567,21 +566,18 @@ nsHostResolver::ResolveHost(const char  
                 result = he->rec;
             }
             // try parsing the host name as an IP address literal to short
             // circuit full host resolution.  (this is necessary on some
             // platforms like Win9x.  see bug 219376 for more details.)
             else if (PR_StringToNetAddr(host, &tempAddr) == PR_SUCCESS) {
                 // ok, just copy the result into the host record, and be done
                 // with it! ;-)
-                he->rec->addr = (PRNetAddr *) malloc(sizeof(PRNetAddr));
-                if (!he->rec->addr)
-                    status = NS_ERROR_OUT_OF_MEMORY;
-                else
-                    memcpy(he->rec->addr, &tempAddr, sizeof(PRNetAddr));
+                he->rec->addr = new NetAddr();
+                PRNetAddrToNetAddr(&tempAddr, he->rec->addr);
                 // put reference to host record on stack...
                 Telemetry::Accumulate(Telemetry::DNS_LOOKUP_METHOD2,
                                       METHOD_LITERAL);
                 result = he->rec;
             }
             else if (mPendingCount >= MAX_NON_PRIORITY_REQUESTS &&
                      !IsHighPriority(flags) &&
                      !he->rec->resolving) {
@@ -815,39 +811,39 @@ nsHostResolver::GetHostToLookup(nsHostRe
     }
     
     // tell thread to exit...
     mThreadCount--;
     return false;
 }
 
 void
-nsHostResolver::OnLookupComplete(nsHostRecord *rec, nsresult status, PRAddrInfo *result)
+nsHostResolver::OnLookupComplete(nsHostRecord *rec, nsresult status, AddrInfo *result)
 {
     // get the list of pending callbacks for this lookup, and notify
     // them that the lookup is complete.
     PRCList cbs;
     PR_INIT_CLIST(&cbs);
     {
         MutexAutoLock lock(mLock);
 
         // grab list of callbacks to notify
         MoveCList(rec->callbacks, cbs);
 
         // update record fields.  We might have a rec->addr_info already if a
         // previous lookup result expired and we're reresolving it..
-        PRAddrInfo  *old_addr_info;
+        AddrInfo  *old_addr_info;
         {
             MutexAutoLock lock(rec->addr_info_lock);
             old_addr_info = rec->addr_info;
             rec->addr_info = result;
             rec->addr_info_gencnt++;
         }
-        if (old_addr_info)
-            PR_FreeAddrInfo(old_addr_info);
+        delete old_addr_info;
+
         rec->expiration = NowInMinutes();
         if (result) {
             rec->expiration += mMaxCacheLifetime;
             rec->negative = false;
         }
         else {
             rec->expiration += 1;                 /* one minute for negative cache */
             rec->negative = true;
@@ -953,38 +949,41 @@ nsHostResolver::ThreadFunc(void *arg)
     static nsThreadPoolNaming naming;
     naming.SetThreadPoolName(NS_LITERAL_CSTRING("DNS Resolver"));
 
 #if defined(RES_RETRY_ON_FAILURE)
     nsResState rs;
 #endif
     nsHostResolver *resolver = (nsHostResolver *)arg;
     nsHostRecord *rec;
-    PRAddrInfo *ai;
+    PRAddrInfo *prai = nullptr;
     while (resolver->GetHostToLookup(&rec)) {
         LOG(("Calling getaddrinfo for host [%s].\n", rec->host));
 
         int flags = PR_AI_ADDRCONFIG;
         if (!(rec->flags & RES_CANON_NAME))
             flags |= PR_AI_NOCANONNAME;
 
         TimeStamp startTime = TimeStamp::Now();
 
-        ai = PR_GetAddrInfoByName(rec->host, rec->af, flags);
+        prai = PR_GetAddrInfoByName(rec->host, rec->af, flags);
 #if defined(RES_RETRY_ON_FAILURE)
-        if (!ai && rs.Reset())
-            ai = PR_GetAddrInfoByName(rec->host, rec->af, flags);
+        if (!prai && rs.Reset())
+            prai = PR_GetAddrInfoByName(rec->host, rec->af, flags);
 #endif
 
         TimeDuration elapsed = TimeStamp::Now() - startTime;
         uint32_t millis = static_cast<uint32_t>(elapsed.ToMilliseconds());
 
-        // convert error code to nsresult.
+        // convert error code to nsresult
         nsresult status;
-        if (ai) {
+        AddrInfo *ai = nullptr;
+        if (prai) {
+            ai = new AddrInfo(rec->host, prai);
+
             status = NS_OK;
 
             Telemetry::Accumulate(!rec->addr_info_gencnt ?
                                     Telemetry::DNS_LOOKUP_TIME :
                                     Telemetry::DNS_RENEWAL_TIME,
                                   millis);
         }
         else {
@@ -1027,54 +1026,54 @@ nsHostResolver::Create(uint32_t         
     *result = res;
     return rv;
 }
 
 PLDHashOperator
 CacheEntryEnumerator(PLDHashTable *table, PLDHashEntryHdr *entry,
                      uint32_t number, void *arg)
 {
-    nsHostDBEnt *ent = static_cast<nsHostDBEnt *> (entry);
-    nsTArray<DNSCacheEntries> *args =
-        static_cast<nsTArray<DNSCacheEntries> *> (arg);
-    nsHostRecord *rec = ent->rec;
-    // Without addr_info, there is no meaning of adding this entry
-    if (rec->addr_info) {
-        DNSCacheEntries info;
-        const char *hostname;
-        PRNetAddr addr;
+    // We don't pay attention to address literals, only resolved domains.
+    // Also require a host.
+    nsHostRecord *rec = static_cast<nsHostDBEnt*>(entry)->rec;
+    if (!rec->addr_info || !rec->host) {
+        return PL_DHASH_NEXT;
+    }
 
-        if (rec->host)
-            hostname = rec->host;
-        else // No need to add this entry if no host name is there
-            return PL_DHASH_NEXT;
+    DNSCacheEntries info;
+    info.hostname = rec->host;
+    info.family = rec->af;
+    info.expiration = ((int64_t)rec->expiration - NowInMinutes()) * 60;
+    if (info.expiration <= 0) {
+        // We only need valid DNS cache entries
+        return PL_DHASH_NEXT;
+    }
 
-        uint32_t now = NowInMinutes();
-        info.expiration = ((int64_t) rec->expiration - now) * 60;
-
-        // We only need valid DNS cache entries
-        if (info.expiration <= 0)
-            return PL_DHASH_NEXT;
+    {
+        MutexAutoLock lock(rec->addr_info_lock);
 
-        info.family = rec->af;
-        info.hostname = hostname;
-
-        {
-            MutexAutoLock lock(rec->addr_info_lock);
-            void *ptr = PR_EnumerateAddrInfo(nullptr, rec->addr_info, 0, &addr);
-            while (ptr) {
-                char buf[64];
-                if (PR_NetAddrToString(&addr, buf, sizeof(buf)) == PR_SUCCESS)
-                    info.hostaddr.AppendElement(buf);
-                ptr = PR_EnumerateAddrInfo(ptr, rec->addr_info, 0, &addr);
+        NetAddr *addr = nullptr;
+        NetAddrElement *addrElement = rec->addr_info->mAddresses.getFirst();
+        if (addrElement) {
+            addr = &addrElement->mAddress;
+        }
+        while (addr) {
+            char buf[kIPv6CStrBufSize];
+            if (NetAddrToString(addr, buf, sizeof(buf))) {
+                info.hostaddr.AppendElement(buf);
+            }
+            addrElement = addrElement->getNext();
+            if (addrElement) {
+                addr = &addrElement->mAddress;
             }
         }
+    }
 
-        args->AppendElement(info);
-    }
+    nsTArray<DNSCacheEntries> *args = static_cast<nsTArray<DNSCacheEntries> *>(arg);
+    args->AppendElement(info);
 
     return PL_DHASH_NEXT;
 }
 
 void
 nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries> *args)
 {
     PL_DHashTableEnumerate(&mDB, CacheEntryEnumerator, args);
--- a/netwerk/dns/nsHostResolver.h
+++ b/netwerk/dns/nsHostResolver.h
@@ -12,16 +12,17 @@
 #include "prnetdb.h"
 #include "pldhash.h"
 #include "mozilla/CondVar.h"
 #include "mozilla/Mutex.h"
 #include "nsISupportsImpl.h"
 #include "nsIDNSListener.h"
 #include "nsString.h"
 #include "nsTArray.h"
+#include "mozilla/net/DNS.h"
 #include "mozilla/net/DashboardTypes.h"
 
 class nsHostResolver;
 class nsHostRecord;
 class nsResolveHostCallback;
 
 #define MAX_RESOLVER_THREADS_FOR_ANY_PRIORITY  3
 #define MAX_RESOLVER_THREADS_FOR_HIGH_PRIORITY 5
@@ -64,31 +65,31 @@ public:
      * nsDNSService2 class.  |addr| doesn't change after it has been
      * assigned a value.  only the resolver worker thread modifies
      * nsHostRecord (and only in nsHostResolver::OnLookupComplete);
      * the other threads just read it.  therefore the resolver worker
      * thread doesn't need to lock when reading |addr_info|.
      */
     Mutex        addr_info_lock;
     int          addr_info_gencnt; /* generation count of |addr_info| */
-    PRAddrInfo  *addr_info;
-    PRNetAddr   *addr;
+    mozilla::net::AddrInfo *addr_info;
+    mozilla::net::NetAddr  *addr;
     bool         negative;   /* True if this record is a cache of a failed lookup.
                                 Negative cache entries are valid just like any other
                                 (though never for more than 60 seconds), but a use
                                 of that negative entry forces an asynchronous refresh. */
 
     uint32_t     expiration; /* measured in minutes since epoch */
 
     bool HasResult() const { return addr_info || addr || negative; }
 
     // hold addr_info_lock when calling the blacklist functions
-    bool Blacklisted(PRNetAddr *query);
+    bool   Blacklisted(mozilla::net::NetAddr *query);
     void   ResetBlacklist();
-    void   ReportUnusable(PRNetAddr *addr);
+    void   ReportUnusable(mozilla::net::NetAddr *addr);
 
 private:
     friend class nsHostResolver;
 
     PRCList callbacks; /* list of callbacks */
 
     bool    resolving; /* true if this record is being resolved, which means
                         * that it is either on the pending queue or owned by
@@ -233,17 +234,17 @@ public:
 private:
     nsHostResolver(uint32_t maxCacheEntries = 50, uint32_t maxCacheLifetime = 1,
                    uint32_t lifetimeGracePeriod = 0);
    ~nsHostResolver();
 
     nsresult Init();
     nsresult IssueLookup(nsHostRecord *);
     bool     GetHostToLookup(nsHostRecord **m);
-    void     OnLookupComplete(nsHostRecord *, nsresult, PRAddrInfo *);
+    void     OnLookupComplete(nsHostRecord *, nsresult, mozilla::net::AddrInfo *);
     void     DeQueue(PRCList &aQ, nsHostRecord **aResult);
     void     ClearPendingQueue(PRCList *aPendingQueue);
     nsresult ConditionallyCreateThread(nsHostRecord *rec);
     
     static void  MoveQueue(nsHostRecord *aRec, PRCList &aDestQ);
     
     static void ThreadFunc(void *);
 
--- a/netwerk/dns/nsIDNSRecord.idl
+++ b/netwerk/dns/nsIDNSRecord.idl
@@ -1,46 +1,49 @@
 /* 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/. */
 
 #include "nsISupports.idl"
 
-native PRNetAddr(union PRNetAddr);
+%{ C++
+#include "mozilla/net/DNS.h"
+%}
+native NetAddr(mozilla::net::NetAddr);
 
 /**
  * nsIDNSRecord
  *
  * this interface represents the result of a DNS lookup.  since a DNS
  * query may return more than one resolved IP address, the record acts
  * like an enumerator, allowing the caller to easily step through the
  * list of IP addresses.
  */
-[scriptable, uuid(ead9e9d8-7eef-4dae-a7f0-a1edcfb20478)]
+[scriptable, uuid(67E6CF03-12C7-4AF4-AE5F-AE362C7AF8FF)]
 interface nsIDNSRecord : nsISupports
 {
     /**
      * @return the canonical hostname for this record.  this value is empty if
      * the record was not fetched with the RESOLVE_CANONICAL_NAME flag.
      *
      * e.g., www.mozilla.org --> rheet.mozilla.org
      */
     readonly attribute ACString canonicalName;
 
     /**
      * this function copies the value of the next IP address into the
-     * given PRNetAddr struct and increments the internal address iterator.
+     * given NetAddr struct and increments the internal address iterator.
      *
      * @param aPort
-     *        A port number to initialize the PRNetAddr with.
+     *        A port number to initialize the NetAddr with.
      *
      * @throws NS_ERROR_NOT_AVAILABLE if there is not another IP address in
      * the record.
      */
-    [noscript] PRNetAddr getNextAddr(in uint16_t aPort);
+    [noscript] NetAddr getNextAddr(in uint16_t aPort);
 
     /**
      * this function returns the value of the next IP address as a
      * string and increments the internal address iterator.
      *
      * @throws NS_ERROR_NOT_AVAILABLE if there is not another IP address in
      * the record.
      */
--- a/netwerk/ipc/NeckoMessageUtils.h
+++ b/netwerk/ipc/NeckoMessageUtils.h
@@ -6,16 +6,17 @@
 #ifndef mozilla_net_NeckoMessageUtils_h
 #define mozilla_net_NeckoMessageUtils_h
 
 #include "mozilla/DebugOnly.h"
 
 #include "ipc/IPCMessageUtils.h"
 #include "nsStringGlue.h"
 #include "prio.h"
+#include "mozilla/net/DNS.h"
 
 namespace IPC {
 
 // nsIPermissionManager utilities
 
 struct Permission
 {
   nsCString host, type;
@@ -80,65 +81,65 @@ struct ParamTraits<Permission>
     LogParam(p.expireTime, l);
     l->append(L", ");
     LogParam(p.expireType, l);
     l->append(L")");
   }
 };
 
 template<>
-struct ParamTraits<PRNetAddr>
+struct ParamTraits<mozilla::net::NetAddr>
 {
-  static void Write(Message* aMsg, const PRNetAddr &aParam)
+  static void Write(Message* aMsg, const mozilla::net::NetAddr &aParam)
   {
     WriteParam(aMsg, aParam.raw.family);
-    if (aParam.raw.family == PR_AF_UNSPEC) {
+    if (aParam.raw.family == AF_UNSPEC) {
       aMsg->WriteBytes(aParam.raw.data, sizeof(aParam.raw.data));
-    } else if (aParam.raw.family == PR_AF_INET) {
+    } else if (aParam.raw.family == AF_INET) {
       WriteParam(aMsg, aParam.inet.port);
       WriteParam(aMsg, aParam.inet.ip);
-    } else if (aParam.raw.family == PR_AF_INET6) {
-      WriteParam(aMsg, aParam.ipv6.port);
-      WriteParam(aMsg, aParam.ipv6.flowinfo);
-      WriteParam(aMsg, aParam.ipv6.ip.pr_s6_addr64[0]);
-      WriteParam(aMsg, aParam.ipv6.ip.pr_s6_addr64[1]);
-      WriteParam(aMsg, aParam.ipv6.scope_id);
+    } else if (aParam.raw.family == AF_INET6) {
+      WriteParam(aMsg, aParam.inet6.port);
+      WriteParam(aMsg, aParam.inet6.flowinfo);
+      WriteParam(aMsg, aParam.inet6.ip.u64[0]);
+      WriteParam(aMsg, aParam.inet6.ip.u64[1]);
+      WriteParam(aMsg, aParam.inet6.scope_id);
 #if defined(XP_UNIX) || defined(XP_OS2)
-    } else if (aParam.raw.family == PR_AF_LOCAL) {
+    } else if (aParam.raw.family == AF_LOCAL) {
       // Train's already off the rails:  let's get a stack trace at least...
       NS_RUNTIMEABORT("Error: please post stack trace to "
                       "https://bugzilla.mozilla.org/show_bug.cgi?id=661158");
       aMsg->WriteBytes(aParam.local.path, sizeof(aParam.local.path));
 #endif
     }
 
     /* If we get here without hitting any of the cases above, there's not much
      * we can do but let the deserializer fail when it gets this message */
   }
 
-  static bool Read(const Message* aMsg, void** aIter, PRNetAddr* aResult)
+  static bool Read(const Message* aMsg, void** aIter, mozilla::net::NetAddr* aResult)
   {
     if (!ReadParam(aMsg, aIter, &aResult->raw.family))
       return false;
 
-    if (aResult->raw.family == PR_AF_UNSPEC) {
+    if (aResult->raw.family == AF_UNSPEC) {
       return aMsg->ReadBytes(aIter,
                              reinterpret_cast<const char**>(&aResult->raw.data),
                              sizeof(aResult->raw.data));
-    } else if (aResult->raw.family == PR_AF_INET) {
+    } else if (aResult->raw.family == AF_INET) {
       return ReadParam(aMsg, aIter, &aResult->inet.port) &&
              ReadParam(aMsg, aIter, &aResult->inet.ip);
-    } else if (aResult->raw.family == PR_AF_INET6) {
-      return ReadParam(aMsg, aIter, &aResult->ipv6.port) &&
-             ReadParam(aMsg, aIter, &aResult->ipv6.flowinfo) &&
-             ReadParam(aMsg, aIter, &aResult->ipv6.ip.pr_s6_addr64[0]) &&
-             ReadParam(aMsg, aIter, &aResult->ipv6.ip.pr_s6_addr64[1]) &&
-             ReadParam(aMsg, aIter, &aResult->ipv6.scope_id);
+    } else if (aResult->raw.family == AF_INET6) {
+      return ReadParam(aMsg, aIter, &aResult->inet6.port) &&
+             ReadParam(aMsg, aIter, &aResult->inet6.flowinfo) &&
+             ReadParam(aMsg, aIter, &aResult->inet6.ip.u64[0]) &&
+             ReadParam(aMsg, aIter, &aResult->inet6.ip.u64[1]) &&
+             ReadParam(aMsg, aIter, &aResult->inet6.scope_id);
 #if defined(XP_UNIX) || defined(XP_OS2)
-    } else if (aResult->raw.family == PR_AF_LOCAL) {
+    } else if (aResult->raw.family == AF_LOCAL) {
       return aMsg->ReadBytes(aIter,
                              reinterpret_cast<const char**>(&aResult->local.path),
                              sizeof(aResult->local.path));
 #endif
     }
 
     /* We've been tricked by some socket family we don't know about! */
     return false;
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -37,16 +37,18 @@
 #include "nsICancelable.h"
 
 #if defined(PR_LOGGING)
 extern PRLogModuleInfo* gFTPLog;
 #endif
 #define LOG(args)         PR_LOG(gFTPLog, PR_LOG_DEBUG, args)
 #define LOG_ALWAYS(args)  PR_LOG(gFTPLog, PR_LOG_ALWAYS, args)
 
+using namespace mozilla::net;
+
 // remove FTP parameters (starting with ";") from the path
 static void
 removeParamsFromPath(nsCString& path)
 {
   int32_t index = path.FindChar(';');
   if (index >= 0) {
     path.SetLength(index);
   }
@@ -1287,45 +1289,46 @@ nsFtpState::R_stor() {
 }
 
 
 nsresult
 nsFtpState::S_pasv() {
     if (!mAddressChecked) {
         // Find socket address
         mAddressChecked = true;
-        PR_InitializeNetAddr(PR_IpAddrAny, 0, &mServerAddress);
+        mServerAddress.raw.family = AF_INET;
+        mServerAddress.inet.ip = htonl(INADDR_ANY);
+        mServerAddress.inet.port = htons(0);
 
         nsITransport *controlSocket = mControlConnection->Transport();
         if (!controlSocket)
             // XXX Invalid cast of FTP_STATE to nsresult -- FTP_ERROR has
             // value < 0x80000000 and will pass NS_SUCCEEDED() (bug 778109)
             return (nsresult)FTP_ERROR;
 
         nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface(controlSocket);
         if (sTrans) {
             nsresult rv = sTrans->GetPeerAddr(&mServerAddress);
             if (NS_SUCCEEDED(rv)) {
-                if (!PR_IsNetAddrType(&mServerAddress, PR_IpAddrAny))
-                    mServerIsIPv6 = mServerAddress.raw.family == PR_AF_INET6 &&
-                        !PR_IsNetAddrType(&mServerAddress, PR_IpAddrV4Mapped);
+                if (!IsIPAddrAny(&mServerAddress))
+                    mServerIsIPv6 = (mServerAddress.raw.family == AF_INET6) &&
+                                    !IsIPAddrV4Mapped(&mServerAddress);
                 else {
                     /*
                      * In case of SOCKS5 remote DNS resolution, we do
                      * not know the remote IP address. Still, if it is
                      * an IPV6 host, then the external address of the
                      * socks server should also be IPv6, and this is the
                      * self address of the transport.
                      */
-                    PRNetAddr selfAddress;
+                    NetAddr selfAddress;
                     rv = sTrans->GetSelfAddr(&selfAddress);
                     if (NS_SUCCEEDED(rv))
-                        mServerIsIPv6 = selfAddress.raw.family == PR_AF_INET6
-                            && !PR_IsNetAddrType(&selfAddress,
-                                                 PR_IpAddrV4Mapped);
+                        mServerIsIPv6 = (selfAddress.raw.family == AF_INET6) &&
+                                        !IsIPAddrV4Mapped(&selfAddress);
                 }
             }
         }
     }
 
     const char *string;
     if (mServerIsIPv6) {
         string = "EPSV" CRLF;
@@ -1441,19 +1444,19 @@ nsFtpState::R_pasv() {
         nsCOMPtr<nsISocketTransportService> sts =
             do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID);
         if (!sts)
             return FTP_ERROR;
        
         nsCOMPtr<nsISocketTransport> strans;
 
         nsAutoCString host;
-        if (!PR_IsNetAddrType(&mServerAddress, PR_IpAddrAny)) {
-            char buf[64];
-            PR_NetAddrToString(&mServerAddress, buf, sizeof(buf));
+        if (!IsIPAddrAny(&mServerAddress)) {
+            char buf[kIPv6CStrBufSize];
+            NetAddrToString(&mServerAddress, buf, sizeof(buf));
             host.Assign(buf);
         } else {
             /*
              * In case of SOCKS5 remote DNS resolving, the peer address
              * fetched previously will be invalid (0.0.0.0): it is unknown
              * to us. But we can pass on the original hostname to the
              * connect for the data connection.
              */
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.h
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.h
@@ -25,16 +25,17 @@
 #include "nsIProtocolHandler.h"
 #include "nsCOMPtr.h"
 #include "nsIAsyncInputStream.h"
 #include "nsIOutputStream.h"
 #include "nsAutoPtr.h"
 #include "nsIPrompt.h"
 #include "nsITransport.h"
 #include "nsIProxyInfo.h"
+#include "mozilla/net/DNS.h"
 
 #include "nsFtpControlConnection.h"
 
 #include "nsICacheEntryDescriptor.h"
 #include "nsICacheListener.h"
 #include "nsIProtocolProxyCallback.h"
 
 // ftp server types
@@ -253,17 +254,17 @@ private:
     nsCOMPtr<nsITransport>        mDataTransport;
     nsCOMPtr<nsIAsyncInputStream> mDataStream;
     nsCOMPtr<nsIRequest>    mUploadRequest;
     bool                    mAddressChecked;
     bool                    mServerIsIPv6;
     
     static uint32_t         mSessionStartTime;
 
-    PRNetAddr               mServerAddress;
+    mozilla::net::NetAddr   mServerAddress;
 
     // ***** control read gvars
     nsresult                mControlStatus;
     nsCString               mControlReadCarryOverBuf;
 
     nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
     bool                    mDoomCache;
     
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1269,63 +1269,63 @@ HttpBaseChannel::SetCacheKeysRedirectCha
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetLocalAddress(nsACString& addr)
 {
   if (mSelfAddr.raw.family == PR_AF_UNSPEC)
     return NS_ERROR_NOT_AVAILABLE;
 
-  addr.SetCapacity(64);
-  PR_NetAddrToString(&mSelfAddr, addr.BeginWriting(), 64);
+  addr.SetCapacity(kIPv6CStrBufSize);
+  NetAddrToString(&mSelfAddr, addr.BeginWriting(), kIPv6CStrBufSize);
   addr.SetLength(strlen(addr.BeginReading()));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetLocalPort(int32_t* port)
 {
   NS_ENSURE_ARG_POINTER(port);
 
   if (mSelfAddr.raw.family == PR_AF_INET) {
-    *port = (int32_t)PR_ntohs(mSelfAddr.inet.port);
+    *port = (int32_t)ntohs(mSelfAddr.inet.port);
   }
   else if (mSelfAddr.raw.family == PR_AF_INET6) {
-    *port = (int32_t)PR_ntohs(mSelfAddr.ipv6.port);
+    *port = (int32_t)ntohs(mSelfAddr.inet6.port);
   }
   else
     return NS_ERROR_NOT_AVAILABLE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetRemoteAddress(nsACString& addr)
 {
   if (mPeerAddr.raw.family == PR_AF_UNSPEC)
     return NS_ERROR_NOT_AVAILABLE;
 
-  addr.SetCapacity(64);
-  PR_NetAddrToString(&mPeerAddr, addr.BeginWriting(), 64);
+  addr.SetCapacity(kIPv6CStrBufSize);
+  NetAddrToString(&mPeerAddr, addr.BeginWriting(), kIPv6CStrBufSize);
   addr.SetLength(strlen(addr.BeginReading()));
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetRemotePort(int32_t* port)
 {
   NS_ENSURE_ARG_POINTER(port);
 
   if (mPeerAddr.raw.family == PR_AF_INET) {
-    *port = (int32_t)PR_ntohs(mPeerAddr.inet.port);
+    *port = (int32_t)ntohs(mPeerAddr.inet.port);
   }
   else if (mPeerAddr.raw.family == PR_AF_INET6) {
-    *port = (int32_t)PR_ntohs(mPeerAddr.ipv6.port);
+    *port = (int32_t)ntohs(mPeerAddr.inet6.port);
   }
   else
     return NS_ERROR_NOT_AVAILABLE;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -26,16 +26,17 @@
 #include "nsISupportsPriority.h"
 #include "nsIApplicationCache.h"
 #include "nsIResumableChannel.h"
 #include "nsITraceableChannel.h"
 #include "nsILoadContext.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsThreadUtils.h"
 #include "PrivateBrowsingChannel.h"
+#include "mozilla/net/DNS.h"
 
 namespace mozilla {
 namespace net {
 
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild. 
  * - Note that this class has nothing to do with nsBaseChannel, which is an
@@ -183,18 +184,18 @@ public:
         nsCOMPtr<nsIHttpChannel> mChannel;
         
         bool mReady;
     };
 
     nsHttpResponseHead * GetResponseHead() const { return mResponseHead; }
     nsHttpRequestHead * GetRequestHead() { return &mRequestHead; }
 
-    const PRNetAddr& GetSelfAddr() { return mSelfAddr; }
-    const PRNetAddr& GetPeerAddr() { return mPeerAddr; }
+    const NetAddr& GetSelfAddr() { return mSelfAddr; }
+    const NetAddr& GetPeerAddr() { return mPeerAddr; }
 
 public: /* Necko internal use only... */
 
 protected:
 
   // Handle notifying listener, removing from loadgroup if request failed.
   void     DoNotifyListener();
   virtual void DoNotifyListenerCleanup() = 0;
@@ -238,18 +239,18 @@ protected:
   nsRefPtr<nsHttpConnectionInfo>    mConnectionInfo;
   nsCOMPtr<nsIProxyInfo>            mProxyInfo;
 
   nsCString                         mSpec; // ASCII encoded URL spec
   nsCString                         mContentTypeHint;
   nsCString                         mContentCharsetHint;
   nsCString                         mUserSetCookieHeader;
 
-  PRNetAddr                         mSelfAddr;
-  PRNetAddr                         mPeerAddr;
+  NetAddr                           mSelfAddr;
+  NetAddr                           mPeerAddr;
 
   // HTTP Upgrade Data
   nsCString                        mUpgradeProtocol;
   nsCOMPtr<nsIHttpUpgradeListener> mUpgradeProtocolCallback;
 
   // Resumable channel specific data
   nsCString                         mEntityID;
   uint64_t                          mStartPos;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -13,16 +13,17 @@
 #include "nsStringStream.h"
 #include "nsHttpHandler.h"
 #include "nsMimeTypes.h"
 #include "nsNetUtil.h"
 #include "nsSerializationHelper.h"
 #include "base/compiler_specific.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
+#include "mozilla/net/DNS.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 //-----------------------------------------------------------------------------
@@ -168,18 +169,18 @@ class StartRequestEvent : public Channel
                     const nsHttpResponseHead& responseHead,
                     const bool& useResponseHead,
                     const nsHttpHeaderArray& requestHeaders,
                     const bool& isFromCache,
                     const bool& cacheEntryAvailable,
                     const uint32_t& cacheExpirationTime,
                     const nsCString& cachedCharset,
                     const nsCString& securityInfoSerialization,
-                    const PRNetAddr& selfAddr,
-                    const PRNetAddr& peerAddr)
+                    const NetAddr& selfAddr,
+                    const NetAddr& peerAddr)
   : mChild(child)
   , mResponseHead(responseHead)
   , mRequestHeaders(requestHeaders)
   , mUseResponseHead(useResponseHead)
   , mIsFromCache(isFromCache)
   , mCacheEntryAvailable(cacheEntryAvailable)
   , mCacheExpirationTime(cacheExpirationTime)
   , mCachedCharset(cachedCharset)
@@ -200,31 +201,31 @@ class StartRequestEvent : public Channel
   nsHttpResponseHead mResponseHead;
   nsHttpHeaderArray mRequestHeaders;
   bool mUseResponseHead;
   bool mIsFromCache;
   bool mCacheEntryAvailable;
   uint32_t mCacheExpirationTime;
   nsCString mCachedCharset;
   nsCString mSecurityInfoSerialization;
-  PRNetAddr mSelfAddr;
-  PRNetAddr mPeerAddr;
+  NetAddr mSelfAddr;
+  NetAddr mPeerAddr;
 };
 
 bool 
 HttpChannelChild::RecvOnStartRequest(const nsHttpResponseHead& responseHead,
                                      const bool& useResponseHead,
                                      const nsHttpHeaderArray& requestHeaders,
                                      const bool& isFromCache,
                                      const bool& cacheEntryAvailable,
                                      const uint32_t& cacheExpirationTime,
                                      const nsCString& cachedCharset,
                                      const nsCString& securityInfoSerialization,
-                                     const PRNetAddr& selfAddr,
-                                     const PRNetAddr& peerAddr)
+                                     const NetAddr& selfAddr,
+                                     const NetAddr& peerAddr)
 {
   if (mEventQ.ShouldEnqueue()) {
     mEventQ.Enqueue(new StartRequestEvent(this, responseHead, useResponseHead,
                                           requestHeaders, isFromCache,
                                           cacheEntryAvailable,
                                           cacheExpirationTime, cachedCharset,
                                           securityInfoSerialization, selfAddr,
                                           peerAddr));
@@ -240,18 +241,18 @@ void
 HttpChannelChild::OnStartRequest(const nsHttpResponseHead& responseHead,
                                  const bool& useResponseHead,
                                  const nsHttpHeaderArray& requestHeaders,
                                  const bool& isFromCache,
                                  const bool& cacheEntryAvailable,
                                  const uint32_t& cacheExpirationTime,
                                  const nsCString& cachedCharset,
                                  const nsCString& securityInfoSerialization,
-                                 const PRNetAddr& selfAddr,
-                                 const PRNetAddr& peerAddr)
+                                 const NetAddr& selfAddr,
+                                 const NetAddr& peerAddr)
 {
   LOG(("HttpChannelChild::RecvOnStartRequest [this=%x]\n", this));
 
   if (useResponseHead && !mCanceled)
     mResponseHead = new nsHttpResponseHead(responseHead);
 
   if (!securityInfoSerialization.IsEmpty()) {
     NS_DeserializeObject(securityInfoSerialization, 
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -22,16 +22,17 @@
 #include "nsIApplicationCacheChannel.h"
 #include "nsIUploadChannel2.h"
 #include "nsIResumableChannel.h"
 #include "nsIProxiedChannel.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIAssociatedContentSecurity.h"
 #include "nsIChildChannel.h"
 #include "nsIHttpChannelChild.h"
+#include "mozilla/net/DNS.h"
 
 namespace mozilla {
 namespace net {
 
 class HttpChannelChild : public PHttpChannelChild
                        , public HttpBaseChannel
                        , public HttpAsyncAborter<HttpChannelChild>
                        , public nsICacheInfoChannel
@@ -92,18 +93,18 @@ protected:
   bool RecvOnStartRequest(const nsHttpResponseHead& responseHead,
                           const bool& useResponseHead,
                           const nsHttpHeaderArray& requestHeaders,
                           const bool& isFromCache,
                           const bool& cacheEntryAvailable,
                           const uint32_t& cacheExpirationTime,
                           const nsCString& cachedCharset,
                           const nsCString& securityInfoSerialization,
-                          const PRNetAddr& selfAddr,
-                          const PRNetAddr& peerAddr);
+                          const mozilla::net::NetAddr& selfAddr,
+                          const mozilla::net::NetAddr& peerAddr);
   bool RecvOnTransportAndData(const nsresult& status,
                               const uint64_t& progress,
                               const uint64_t& progressMax,
                               const nsCString& data,
                               const uint64_t& offset,
                               const uint32_t& count);
   bool RecvOnStopRequest(const nsresult& statusCode);
   bool RecvOnProgress(const uint64_t& progress, const uint64_t& progressMax);
@@ -146,18 +147,18 @@ private:
   void OnStartRequest(const nsHttpResponseHead& responseHead,
                       const bool& useResponseHead,
                       const nsHttpHeaderArray& requestHeaders,
                       const bool& isFromCache,
                       const bool& cacheEntryAvailable,
                       const uint32_t& cacheExpirationTime,
                       const nsCString& cachedCharset,
                       const nsCString& securityInfoSerialization,
-                      const PRNetAddr& selfAddr,
-                      const PRNetAddr& peerAddr);
+                      const mozilla::net::NetAddr& selfAddr,
+                      const mozilla::net::NetAddr& peerAddr);
   void OnTransportAndData(const nsresult& status,
                           const uint64_t progress,
                           const uint64_t& progressMax,
                           const nsCString& data,
                           const uint64_t& offset,
                           const uint32_t& count);
   void OnStopRequest(const nsresult& statusCode);
   void OnProgress(const uint64_t& progress, const uint64_t& progressMax);
--- a/netwerk/protocol/http/PHttpChannel.ipdl
+++ b/netwerk/protocol/http/PHttpChannel.ipdl
@@ -8,23 +8,24 @@
 include protocol PNecko;
 include InputStreamParams;
 include URIParams;
 
 include protocol PBlob; //FIXME: bug #792908
 
 include "mozilla/net/PHttpChannelParams.h";
 include "mozilla/net/NeckoMessageUtils.h";
+include "mozilla/net/DNS.h";
 include "prio.h";
 
 using RequestHeaderTuples;
 using nsHttpHeaderArray;
 using nsHttpResponseHead;
 using nsHttpAtom;
-using PRNetAddr;
+using mozilla::net::NetAddr;
 
 namespace mozilla {
 namespace net {
 
 //-------------------------------------------------------------------
 protocol PHttpChannel
 {
   manager PNecko;
@@ -97,18 +98,18 @@ child:
   OnStartRequest(nsHttpResponseHead  responseHead,
                  bool                useResponseHead,
                  nsHttpHeaderArray   requestHeaders,
                  bool                isFromCache,
                  bool                cacheEntryAvailable,
                  uint32_t            cacheExpirationTime,
                  nsCString           cachedCharset,
                  nsCString           securityInfoSerialization,
-                 PRNetAddr           selfAddr,
-                 PRNetAddr           peerAddr);
+                 NetAddr             selfAddr,
+                 NetAddr             peerAddr);
 
   // Combines a single OnDataAvailable and its associated OnProgress &
   // OnStatus calls into one IPDL message
   OnTransportAndData(nsresult  status,
                      uint64_t  progress,
                      uint64_t  progressMax,
                      nsCString data,
                      uint64_t  offset,
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -6,16 +6,17 @@
 #include "nsHttpConnectionMgr.h"
 #include "nsHttpConnection.h"
 #include "nsHttpPipeline.h"
 #include "nsHttpHandler.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsNetCID.h"
 #include "nsCOMPtr.h"
 #include "nsNetUtil.h"
+#include "mozilla/net/DNS.h"
 
 #include "nsIServiceManager.h"
 
 #include "nsIObserverService.h"
 
 #include "nsISSLSocketControl.h"
 #include "prnetdb.h"
 #include "mozilla/Telemetry.h"
@@ -2833,21 +2834,21 @@ nsHttpConnectionMgr::nsHalfOpenSocket::O
 
     if (status == NS_NET_STATUS_CONNECTED_TO &&
         gHttpHandler->IsSpdyEnabled() &&
         gHttpHandler->CoalesceSpdy() &&
         mEnt && mEnt->mConnInfo && mEnt->mConnInfo->UsingSSL() &&
         !mEnt->mConnInfo->UsingProxy() &&
         mEnt->mCoalescingKey.IsEmpty()) {
 
-        PRNetAddr addr;
+        NetAddr addr;
         nsresult rv = mSocketTransport->GetPeerAddr(&addr);
         if (NS_SUCCEEDED(rv)) {
-            mEnt->mCoalescingKey.SetCapacity(72);
-            PR_NetAddrToString(&addr, mEnt->mCoalescingKey.BeginWriting(), 64);
+            mEnt->mCoalescingKey.SetCapacity(kIPv6CStrBufSize + 26);
+            NetAddrToString(&addr, mEnt->mCoalescingKey.BeginWriting(), kIPv6CStrBufSize);
             mEnt->mCoalescingKey.SetLength(
                 strlen(mEnt->mCoalescingKey.BeginReading()));
 
             if (mEnt->mConnInfo->GetAnonymous())
                 mEnt->mCoalescingKey.AppendLiteral("~A:");
             else
                 mEnt->mCoalescingKey.AppendLiteral("~.:");
             mEnt->mCoalescingKey.AppendInt(mEnt->mConnInfo->Port());
--- a/netwerk/socket/nsISOCKSSocketInfo.idl
+++ b/netwerk/socket/nsISOCKSSocketInfo.idl
@@ -1,17 +1,20 @@
 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  *
  * 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/. */
 
 #include "nsISupports.idl"
 
-[ptr] native PRNetAddrPtr(union PRNetAddr);
+%{ C++
+#include "mozilla/net/DNS.h"
+%}
+[ptr] native NetAddrPtr(mozilla::net::NetAddr);
 
-[scriptable, uuid(8f755c44-1dd2-11b2-a613-91117453fa95)]
+[scriptable, uuid(D5C0D1F9-22D7-47DC-BF91-D9AC6E1251A6)]
 interface nsISOCKSSocketInfo : nsISupports
 {
-    [noscript] attribute PRNetAddrPtr destinationAddr;
-    [noscript] attribute PRNetAddrPtr externalProxyAddr;
-    [noscript] attribute PRNetAddrPtr internalProxyAddr;
+    [noscript] attribute NetAddrPtr destinationAddr;
+    [noscript] attribute NetAddrPtr externalProxyAddr;
+    [noscript] attribute NetAddrPtr internalProxyAddr;
 };
--- a/netwerk/socket/nsSOCKSIOLayer.cpp
+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
@@ -14,19 +14,22 @@
 #include "nsIDNSRecord.h"
 #include "nsISOCKSSocketInfo.h"
 #include "nsISocketProvider.h"
 #include "nsSOCKSIOLayer.h"
 #include "nsNetCID.h"
 #include "nsIDNSListener.h"
 #include "nsICancelable.h"
 #include "nsThreadUtils.h"
+#include "mozilla/net/DNS.h"
 
-static PRDescIdentity	nsSOCKSIOLayerIdentity;
-static PRIOMethods	nsSOCKSIOLayerMethods;
+using namespace mozilla::net;
+
+static PRDescIdentity nsSOCKSIOLayerIdentity;
+static PRIOMethods nsSOCKSIOLayerMethods;
 static bool firstTime = true;
 static bool ipv6Supported = true;
 
 #if defined(PR_LOGGING)
 static PRLogModuleInfo *gSOCKSLog;
 #define LOGDEBUG(args) PR_LOG(gSOCKSLog, PR_LOG_DEBUG, args)
 #define LOGERROR(args) PR_LOG(gSOCKSLog, PR_LOG_ERROR , args)
 
@@ -79,39 +82,39 @@ public:
     int16_t GetPollFlags() const;
     bool IsConnected() const { return mState == SOCKS_CONNECTED; }
     void ForgetFD() { mFD = nullptr; }
 
 private:
     void HandshakeFinished(PRErrorCode err = 0);
     PRStatus StartDNS(PRFileDesc *fd);
     PRStatus ConnectToProxy(PRFileDesc *fd);
-    void FixupAddressFamily(PRFileDesc *fd, PRNetAddr *proxy);
+    void FixupAddressFamily(PRFileDesc *fd, NetAddr *proxy);
     PRStatus ContinueConnectingToProxy(PRFileDesc *fd, int16_t oflags);
     PRStatus WriteV4ConnectRequest();
     PRStatus ReadV4ConnectResponse();
     PRStatus WriteV5AuthRequest();
     PRStatus ReadV5AuthResponse();
     PRStatus WriteV5ConnectRequest();
     PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
     PRStatus ReadV5ConnectResponseTop();
     PRStatus ReadV5ConnectResponseBottom();
 
     void WriteUint8(uint8_t d);
     void WriteUint16(uint16_t d);
     void WriteUint32(uint32_t d);
-    void WriteNetAddr(const PRNetAddr *addr);
-    void WriteNetPort(const PRNetAddr *addr);
+    void WriteNetAddr(const NetAddr *addr);
+    void WriteNetPort(const NetAddr *addr);
     void WriteString(const nsACString &str);
 
     uint8_t ReadUint8();
     uint16_t ReadUint16();
     uint32_t ReadUint32();
-    void ReadNetAddr(PRNetAddr *addr, uint16_t fam);
-    void ReadNetPort(PRNetAddr *addr);
+    void ReadNetAddr(NetAddr *addr, uint16_t fam);
+    void ReadNetPort(NetAddr *addr);
 
     void WantRead(uint32_t sz);
     PRStatus ReadFromSocket(PRFileDesc *fd);
     PRStatus WriteToSocket(PRFileDesc *fd);
 
 private:
     State     mState;
     uint8_t * mData;
@@ -125,92 +128,101 @@ private:
     PRFileDesc             *mFD;
 
     nsCString mDestinationHost;
     nsCString mProxyHost;
     int32_t   mProxyPort;
     int32_t   mVersion;   // SOCKS version 4 or 5
     int32_t   mDestinationFamily;
     uint32_t  mFlags;
-    PRNetAddr mInternalProxyAddr;
-    PRNetAddr mExternalProxyAddr;
-    PRNetAddr mDestinationAddr;
+    NetAddr   mInternalProxyAddr;
+    NetAddr   mExternalProxyAddr;
+    NetAddr   mDestinationAddr;
     PRIntervalTime mTimeout;
 };
 
 nsSOCKSSocketInfo::nsSOCKSSocketInfo()
     : mState(SOCKS_INITIAL)
     , mDataIoPtr(nullptr)
     , mDataLength(0)
     , mReadOffset(0)
     , mAmountToRead(0)
     , mProxyPort(-1)
     , mVersion(-1)
-    , mDestinationFamily(PR_AF_INET)
+    , mDestinationFamily(AF_INET)
     , mFlags(0)
     , mTimeout(PR_INTERVAL_NO_TIMEOUT)
 {
     mData = new uint8_t[BUFFER_SIZE];
-    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mInternalProxyAddr);
-    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mExternalProxyAddr);
-    PR_InitializeNetAddr(PR_IpAddrAny, 0, &mDestinationAddr);
+
+    mInternalProxyAddr.raw.family = AF_INET;
+    mInternalProxyAddr.inet.ip = htonl(INADDR_ANY);
+    mInternalProxyAddr.inet.port = htons(0);
+
+    mExternalProxyAddr.raw.family = AF_INET;
+    mExternalProxyAddr.inet.ip = htonl(INADDR_ANY);
+    mExternalProxyAddr.inet.port = htons(0);
+
+    mDestinationAddr.raw.family = AF_INET;
+    mDestinationAddr.inet.ip = htonl(INADDR_ANY);
+    mDestinationAddr.inet.port = htons(0);
 }
 
 void
 nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
 {
     mVersion         = version;
     mDestinationFamily = family;
     mProxyHost       = proxyHost;
     mProxyPort       = proxyPort;
     mDestinationHost = host;
     mFlags           = flags;
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::GetExternalProxyAddr(PRNetAddr * *aExternalProxyAddr)
+nsSOCKSSocketInfo::GetExternalProxyAddr(NetAddr * *aExternalProxyAddr)
 {
-    memcpy(*aExternalProxyAddr, &mExternalProxyAddr, sizeof(PRNetAddr));
+    memcpy(*aExternalProxyAddr, &mExternalProxyAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::SetExternalProxyAddr(PRNetAddr *aExternalProxyAddr)
+nsSOCKSSocketInfo::SetExternalProxyAddr(NetAddr *aExternalProxyAddr)
 {
-    memcpy(&mExternalProxyAddr, aExternalProxyAddr, sizeof(PRNetAddr));
+    memcpy(&mExternalProxyAddr, aExternalProxyAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::GetDestinationAddr(PRNetAddr * *aDestinationAddr)
+nsSOCKSSocketInfo::GetDestinationAddr(NetAddr * *aDestinationAddr)
 {
-    memcpy(*aDestinationAddr, &mDestinationAddr, sizeof(PRNetAddr));
+    memcpy(*aDestinationAddr, &mDestinationAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::SetDestinationAddr(PRNetAddr *aDestinationAddr)
+nsSOCKSSocketInfo::SetDestinationAddr(NetAddr *aDestinationAddr)
 {
-    memcpy(&mDestinationAddr, aDestinationAddr, sizeof(PRNetAddr));
+    memcpy(&mDestinationAddr, aDestinationAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::GetInternalProxyAddr(PRNetAddr * *aInternalProxyAddr)
+nsSOCKSSocketInfo::GetInternalProxyAddr(NetAddr * *aInternalProxyAddr)
 {
-    memcpy(*aInternalProxyAddr, &mInternalProxyAddr, sizeof(PRNetAddr));
+    memcpy(*aInternalProxyAddr, &mInternalProxyAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 NS_IMETHODIMP 
-nsSOCKSSocketInfo::SetInternalProxyAddr(PRNetAddr *aInternalProxyAddr)
+nsSOCKSSocketInfo::SetInternalProxyAddr(NetAddr *aInternalProxyAddr)
 {
-    memcpy(&mInternalProxyAddr, aInternalProxyAddr, sizeof(PRNetAddr));
+    memcpy(&mInternalProxyAddr, aInternalProxyAddr, sizeof(NetAddr));
     return NS_OK;
 }
 
 // There needs to be a means of distinguishing between connection errors
 // that the SOCKS server reports when it rejects a connection request, and
 // connection errors that happen while attempting to connect to the SOCKS
 // server. Otherwise, Firefox will report incorrectly that the proxy server
 // is refusing connections when a SOCKS request is rejected by the proxy.
@@ -292,17 +304,17 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFile
 
     if (NS_FAILED(mLookupStatus)) {
         PR_SetError(PR_BAD_ADDRESS_ERROR, 0);
         return PR_FAILURE;
     }
 
     // Try socks5 if the destination addrress is IPv6
     if (mVersion == 4 &&
-        PR_NetAddrFamily(&mDestinationAddr) == PR_AF_INET6) {
+        mDestinationAddr.raw.family == AF_INET6) {
         mVersion = 5;
     }
 
     int32_t addresses = 0;
     do {
         if (addresses++)
             mDnsRec->ReportUnusable(mProxyPort);
         
@@ -310,24 +322,26 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFile
         // No more addresses to try? If so, we'll need to bail
         if (NS_FAILED(rv)) {
             LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
                      mProxyHost.get()));
             return PR_FAILURE;
         }
 
 #if defined(PR_LOGGING)
-        char buf[64];
-        PR_NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
+        char buf[kIPv6CStrBufSize];
+        NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
         LOGDEBUG(("socks: trying proxy server, %s:%hu",
-                 buf, PR_ntohs(PR_NetAddrInetPort(&mInternalProxyAddr))));
+                 buf, ntohs(mInternalProxyAddr.inet.port)));
 #endif
-        PRNetAddr proxy = mInternalProxyAddr;
+        NetAddr proxy = mInternalProxyAddr;
         FixupAddressFamily(fd, &proxy);
-        status = fd->lower->methods->connect(fd->lower, &proxy, mTimeout);
+        PRNetAddr prProxy;
+        NetAddrToPRNetAddr(&proxy, &prProxy);
+        status = fd->lower->methods->connect(fd->lower, &prProxy, mTimeout);
         if (status != PR_SUCCESS) {
             PRErrorCode c = PR_GetError();
             // If EINPROGRESS, return now and check back later after polling
             if (c == PR_WOULD_BLOCK_ERROR || c == PR_IN_PROGRESS_ERROR) {
                 mState = SOCKS_CONNECTING_TO_PROXY;
                 return status;
             }
         }
@@ -335,35 +349,35 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFile
 
     // Connected now, start SOCKS
     if (mVersion == 4)
         return WriteV4ConnectRequest();
     return WriteV5AuthRequest();
 }
 
 void
-nsSOCKSSocketInfo::FixupAddressFamily(PRFileDesc *fd, PRNetAddr *proxy)
+nsSOCKSSocketInfo::FixupAddressFamily(PRFileDesc *fd, NetAddr *proxy)
 {
-    int32_t proxyFamily = PR_NetAddrFamily(&mInternalProxyAddr);
+    int32_t proxyFamily = mInternalProxyAddr.raw.family;
     // Do nothing if the address family is already matched
     if (proxyFamily == mDestinationFamily) {
         return;
     }
     // If the system does not support IPv6 and the proxy address is IPv6,
     // We can do nothing here.
-    if (proxyFamily == PR_AF_INET6 && !ipv6Supported) {
+    if (proxyFamily == AF_INET6 && !ipv6Supported) {
         return;
     }
     // If the system does not support IPv6 and the destination address is
     // IPv6, convert IPv4 address to IPv4-mapped IPv6 address to satisfy
     // the emulation layer
-    if (mDestinationFamily == PR_AF_INET6 && !ipv6Supported) {
-        proxy->ipv6.family = PR_AF_INET6;
-        proxy->ipv6.port = mInternalProxyAddr.inet.port;
-        uint8_t *proxyp = proxy->ipv6.ip.pr_s6_addr;
+    if (mDestinationFamily == AF_INET6 && !ipv6Supported) {
+        proxy->inet6.family = AF_INET6;
+        proxy->inet6.port = mInternalProxyAddr.inet.port;
+        uint8_t *proxyp = proxy->inet6.ip.u8;
         memset(proxyp, 0, 10);
         memset(proxyp + 10, 0xff, 2);
         memcpy(proxyp + 12,(char *) &mInternalProxyAddr.inet.ip, 4);
         // mDestinationFamily should not be updated
         return;
     }
     // Get an OS native handle from a specified FileDesc
     PROsfd osfd = PR_FileDesc2NativeHandle(fd);
@@ -419,17 +433,17 @@ nsSOCKSSocketInfo::ContinueConnectingToP
     if (mVersion == 4)
         return WriteV4ConnectRequest();
     return WriteV5AuthRequest();
 }
 
 PRStatus
 nsSOCKSSocketInfo::WriteV4ConnectRequest()
 {
-    PRNetAddr *addr = &mDestinationAddr;
+    NetAddr *addr = &mDestinationAddr;
     int32_t proxy_resolve;
 
     NS_ABORT_IF_FALSE(mState == SOCKS_CONNECTING_TO_PROXY,
                       "Invalid state!");
     
     proxy_resolve = mFlags & nsISocketProvider::PROXY_RESOLVES_HOST;
 
     mDataLength = 0;
@@ -443,29 +457,29 @@ nsSOCKSSocketInfo::WriteV4ConnectRequest
     WriteUint8(0x01); // command -- connect
     WriteNetPort(addr);
     if (proxy_resolve) {
         // Add the full name, null-terminated, to the request
         // according to SOCKS 4a. A fake IP address, with the first
         // four bytes set to 0 and the last byte set to something other
         // than 0, is used to notify the proxy that this is a SOCKS 4a
         // request. This request type works for Tor and perhaps others.
-        WriteUint32(PR_htonl(0x00000001)); // Fake IP
+        WriteUint32(htonl(0x00000001)); // Fake IP
         WriteUint8(0x00); // Send an emtpy username
         if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
             LOGERROR(("socks4: destination host name is too long!"));
             HandshakeFinished(PR_BAD_ADDRESS_ERROR);
             return PR_FAILURE;
         }
         WriteString(mDestinationHost); // Hostname
         WriteUint8(0x00);
-    } else if (PR_NetAddrFamily(addr) == PR_AF_INET) {
+    } else if (addr->raw.family == AF_INET) {
         WriteNetAddr(addr); // Add the IPv4 address
         WriteUint8(0x00); // Send an emtpy username
-    } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) {
+    } else if (addr->raw.family == AF_INET6) {
         LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
         HandshakeFinished(PR_BAD_ADDRESS_ERROR);
         return PR_FAILURE;
     }
 
     return PR_SUCCESS;
 }
 
@@ -539,17 +553,17 @@ nsSOCKSSocketInfo::ReadV5AuthResponse()
 
     return WriteV5ConnectRequest();
 }
 
 PRStatus
 nsSOCKSSocketInfo::WriteV5ConnectRequest()
 {
     // Send SOCKS 5 connect request
-    PRNetAddr *addr = &mDestinationAddr;
+    NetAddr *addr = &mDestinationAddr;
     int32_t proxy_resolve;
     proxy_resolve = mFlags & nsISocketProvider::PROXY_RESOLVES_HOST;
 
     LOGDEBUG(("socks5: sending connection request (socks5 resolve? %s)",
              proxy_resolve? "yes" : "no"));
 
     mDataLength = 0;
     mState = SOCKS5_WRITE_CONNECT_REQUEST;
@@ -566,20 +580,20 @@ nsSOCKSSocketInfo::WriteV5ConnectRequest
         if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
             LOGERROR(("socks5: destination host name is too long!"));
             HandshakeFinished(PR_BAD_ADDRESS_ERROR);
             return PR_FAILURE;
         }
         WriteUint8(0x03); // addr type -- domainname
         WriteUint8(mDestinationHost.Length()); // name length
         WriteString(mDestinationHost);
-    } else if (PR_NetAddrFamily(addr) == PR_AF_INET) {
+    } else if (addr->raw.family == AF_INET) {
         WriteUint8(0x01); // addr type -- IPv4
         WriteNetAddr(addr);
-    } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) {
+    } else if (addr->raw.family == AF_INET6) {
         WriteUint8(0x04); // addr type -- IPv6
         WriteNetAddr(addr);
     } else {
         LOGERROR(("socks5: destination address of unknown type!"));
         HandshakeFinished(PR_BAD_ADDRESS_ERROR);
         return PR_FAILURE;
     }
 
@@ -713,24 +727,24 @@ nsSOCKSSocketInfo::ReadV5ConnectResponse
 
     NS_ABORT_IF_FALSE(mDataLength == 7+len,
                       "SOCKS 5 unexpected length of connection reply!");
 
     LOGDEBUG(("socks5: loading source addr and port"));
     // Read what the proxy says is our source address
     switch (type) {
         case 0x01: // ipv4
-            ReadNetAddr(&mExternalProxyAddr, PR_AF_INET);
+            ReadNetAddr(&mExternalProxyAddr, AF_INET);
             break;
         case 0x04: // ipv6
-            ReadNetAddr(&mExternalProxyAddr, PR_AF_INET6);
+            ReadNetAddr(&mExternalProxyAddr, AF_INET6);
             break;
         case 0x03: // fqdn (skip)
             mReadOffset += len;
-            mExternalProxyAddr.raw.family = PR_AF_INET;
+            mExternalProxyAddr.raw.family = AF_INET;
             break;
     }
 
     ReadNetPort(&mExternalProxyAddr);
 
     LOGDEBUG(("socks5: connected!"));
     HandshakeFinished();
 
@@ -860,41 +874,41 @@ nsSOCKSSocketInfo::WriteUint32(uint32_t 
 {
     NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
                       "Can't write that much data!");
     memcpy(mData + mDataLength, &v, sizeof(v));
     mDataLength += sizeof(v);
 }
 
 void
-nsSOCKSSocketInfo::WriteNetAddr(const PRNetAddr *addr)
+nsSOCKSSocketInfo::WriteNetAddr(const NetAddr *addr)
 {
     const char *ip = NULL;
     uint32_t len = 0;
 
-    if (PR_NetAddrFamily(addr) == PR_AF_INET) {
+    if (addr->raw.family == AF_INET) {
         ip = (const char*)&addr->inet.ip;
         len = sizeof(addr->inet.ip);
-    } else if (PR_NetAddrFamily(addr) == PR_AF_INET6) {
-        ip = (const char*)addr->ipv6.ip.pr_s6_addr;
-        len = sizeof(addr->ipv6.ip.pr_s6_addr);
+    } else if (addr->raw.family == AF_INET6) {
+        ip = (const char*)addr->inet6.ip.u8;
+        len = sizeof(addr->inet6.ip.u8);
     }
 
     NS_ABORT_IF_FALSE(ip != NULL, "Unknown address");
     NS_ABORT_IF_FALSE(mDataLength + len <= BUFFER_SIZE,
                       "Can't write that much data!");
  
     memcpy(mData + mDataLength, ip, len);
     mDataLength += len;
 }
 
 void
-nsSOCKSSocketInfo::WriteNetPort(const PRNetAddr *addr)
+nsSOCKSSocketInfo::WriteNetPort(const NetAddr *addr)
 {
-    WriteUint16(PR_NetAddrInetPort(addr));
+    WriteUint16(addr->inet.port);
 }
 
 void
 nsSOCKSSocketInfo::WriteString(const nsACString &str)
 {
     NS_ABORT_IF_FALSE(mDataLength + str.Length() <= BUFFER_SIZE,
                       "Can't write that much data!");
     memcpy(mData + mDataLength, str.Data(), str.Length());
@@ -930,39 +944,39 @@ nsSOCKSSocketInfo::ReadUint32()
     NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
                       "Not enough space to pop a uint32_t!");
     memcpy(&rv, mData + mReadOffset, sizeof(rv));
     mReadOffset += sizeof(rv);
     return rv;
 }
 
 void
-nsSOCKSSocketInfo::ReadNetAddr(PRNetAddr *addr, uint16_t fam)
+nsSOCKSSocketInfo::ReadNetAddr(NetAddr *addr, uint16_t fam)
 {
     uint32_t amt = 0;
     const uint8_t *ip = mData + mReadOffset;
 
     addr->raw.family = fam;
-    if (fam == PR_AF_INET) {
+    if (fam == AF_INET) {
         amt = sizeof(addr->inet.ip);
         NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
                           "Not enough space to pop an ipv4 addr!");
         memcpy(&addr->inet.ip, ip, amt);
-    } else if (fam == PR_AF_INET6) {
-        amt = sizeof(addr->ipv6.ip.pr_s6_addr);
+    } else if (fam == AF_INET6) {
+        amt = sizeof(addr->inet6.ip.u8);
         NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
                           "Not enough space to pop an ipv6 addr!");
-        memcpy(addr->ipv6.ip.pr_s6_addr, ip, amt);
+        memcpy(addr->inet6.ip.u8, ip, amt);
     }
 
     mReadOffset += amt;
 }
 
 void
-nsSOCKSSocketInfo::ReadNetPort(PRNetAddr *addr)
+nsSOCKSSocketInfo::ReadNetPort(NetAddr *addr)
 {
     addr->inet.port = ReadUint16();
 }
 
 void
 nsSOCKSSocketInfo::WantRead(uint32_t sz)
 {
     NS_ABORT_IF_FALSE(mDataIoPtr == NULL,
@@ -1055,32 +1069,34 @@ nsSOCKSSocketInfo::WriteToSocket(PRFileD
     
     return PR_FAILURE;
 }
 
 static PRStatus
 nsSOCKSIOLayerConnect(PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime to)
 {
     PRStatus status;
-    PRNetAddr dst;
+    NetAddr dst;
 
     nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret;
     if (info == NULL) return PR_FAILURE;
 
-    if (PR_NetAddrFamily(addr) == PR_AF_INET6 &&
+    if (addr->raw.family == PR_AF_INET6 &&
         PR_IsNetAddrType(addr, PR_IpAddrV4Mapped)) {
         const uint8_t *srcp;
 
         LOGDEBUG(("socks: converting ipv4-mapped ipv6 address to ipv4"));
 
         // copied from _PR_ConvertToIpv4NetAddr()
-        PR_InitializeNetAddr(PR_IpAddrAny, 0, &dst);
+        dst.raw.family = AF_INET;
+        dst.inet.ip = htonl(INADDR_ANY);
+        dst.inet.port = htons(0);
         srcp = addr->ipv6.ip.pr_s6_addr;
         memcpy(&dst.inet.ip, srcp + 12, 4);
-        dst.inet.family = PR_AF_INET;
+        dst.inet.family = AF_INET;
         dst.inet.port = addr->ipv6.port;
     } else {
         memcpy(&dst, addr, sizeof(dst));
     }
 
     info->SetDestinationAddr(&dst);
     info->SetConnectTimeout(to);
 
@@ -1158,31 +1174,39 @@ nsSOCKSIOLayerBind(PRFileDesc *fd, const
 }
 
 static PRStatus
 nsSOCKSIOLayerGetName(PRFileDesc *fd, PRNetAddr *addr)
 {
     nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret;
     
     if (info != NULL && addr != NULL) {
-        if (info->GetExternalProxyAddr(&addr) == NS_OK)
+        NetAddr temp;
+        NetAddr *tempPtr = &temp;
+        if (info->GetExternalProxyAddr(&tempPtr) == NS_OK) {
+            NetAddrToPRNetAddr(tempPtr, addr);
             return PR_SUCCESS;
+        }
     }
 
     return PR_FAILURE;
 }
 
 static PRStatus
 nsSOCKSIOLayerGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
 {
     nsSOCKSSocketInfo * info = (nsSOCKSSocketInfo*) fd->secret;
 
     if (info != NULL && addr != NULL) {
-        if (info->GetDestinationAddr(&addr) == NS_OK)
+        NetAddr temp;
+        NetAddr *tempPtr = &temp;
+        if (info->GetDestinationAddr(&tempPtr) == NS_OK) {
+            NetAddrToPRNetAddr(tempPtr, addr);
             return PR_SUCCESS;
+        }
     }
 
     return PR_FAILURE;
 }
 
 static PRStatus
 nsSOCKSIOLayerListen(PRFileDesc *fd, int backlog)
 {
@@ -1214,42 +1238,42 @@ nsSOCKSIOLayerAddToSocket(int32_t family
             ipv6Supported = false;
         } else {
             // If the system does not support IPv6, NSPR will push
             // IPv6-to-IPv4 emulation layer onto the native layer
             ipv6Supported = PR_GetIdentitiesLayer(tmpfd, PR_NSPR_IO_LAYER) == tmpfd;
             PR_Close(tmpfd);
         }
 
-        nsSOCKSIOLayerIdentity		= PR_GetUniqueIdentity("SOCKS layer");
-        nsSOCKSIOLayerMethods		= *PR_GetDefaultIOMethods();
+        nsSOCKSIOLayerIdentity = PR_GetUniqueIdentity("SOCKS layer");
+        nsSOCKSIOLayerMethods = *PR_GetDefaultIOMethods();
 
-        nsSOCKSIOLayerMethods.connect	= nsSOCKSIOLayerConnect;
-        nsSOCKSIOLayerMethods.connectcontinue	= nsSOCKSIOLayerConnectContinue;
-        nsSOCKSIOLayerMethods.poll	= nsSOCKSIOLayerPoll;
-        nsSOCKSIOLayerMethods.bind	= nsSOCKSIOLayerBind;
+        nsSOCKSIOLayerMethods.connect = nsSOCKSIOLayerConnect;
+        nsSOCKSIOLayerMethods.connectcontinue = nsSOCKSIOLayerConnectContinue;
+        nsSOCKSIOLayerMethods.poll = nsSOCKSIOLayerPoll;
+        nsSOCKSIOLayerMethods.bind = nsSOCKSIOLayerBind;
         nsSOCKSIOLayerMethods.acceptread = nsSOCKSIOLayerAcceptRead;
         nsSOCKSIOLayerMethods.getsockname = nsSOCKSIOLayerGetName;
         nsSOCKSIOLayerMethods.getpeername = nsSOCKSIOLayerGetPeerName;
-        nsSOCKSIOLayerMethods.accept	= nsSOCKSIOLayerAccept;
-        nsSOCKSIOLayerMethods.listen	= nsSOCKSIOLayerListen;
-        nsSOCKSIOLayerMethods.close	= nsSOCKSIOLayerClose;
+        nsSOCKSIOLayerMethods.accept = nsSOCKSIOLayerAccept;
+        nsSOCKSIOLayerMethods.listen = nsSOCKSIOLayerListen;
+        nsSOCKSIOLayerMethods.close = nsSOCKSIOLayerClose;
 
-        firstTime			= false;
+        firstTime = false;
 
 #if defined(PR_LOGGING)
         gSOCKSLog = PR_NewLogModule("SOCKS");
 #endif
 
     }
 
     LOGDEBUG(("Entering nsSOCKSIOLayerAddToSocket()."));
 
-    PRFileDesc *	layer;
-    PRStatus	rv;
+    PRFileDesc *layer;
+    PRStatus rv;
 
     layer = PR_CreateIOLayerStub(nsSOCKSIOLayerIdentity, &nsSOCKSIOLayerMethods);
     if (! layer)
     {
         LOGERROR(("PR_CreateIOLayerStub() failed."));
         return NS_ERROR_FAILURE;
     }