[tor-commits] [tor-browser/tor-browser-45.3.0esr-6.5-1] Bug 1211567 - Enable domain socket support for SOCKS; r=bagder

gk at torproject.org gk at torproject.org
Tue Aug 30 07:31:04 UTC 2016


commit cde73b2295b75898ca435ed9f78541eccf6c34cb
Author: Liang-Heng Chen <xeonchen at mozilla.com>
Date:   Thu Jun 30 11:23:40 2016 +0800

    Bug 1211567 - Enable domain socket support for SOCKS; r=bagder
    
    MozReview-Commit-ID: 9yMFckwPf6C
    
    --HG--
    extra : rebase_source : 17f006f17f97f015403153879cd8b50e482cfc8c
---
 netwerk/base/nsProtocolProxyService.cpp |  22 +++++--
 netwerk/base/nsProtocolProxyService.h   |   5 +-
 netwerk/socket/nsSOCKSIOLayer.cpp       | 101 ++++++++++++++++++++++++++------
 3 files changed, 104 insertions(+), 24 deletions(-)

diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp
index 593d0af..5d8dc4b 100644
--- a/netwerk/base/nsProtocolProxyService.cpp
+++ b/netwerk/base/nsProtocolProxyService.cpp
@@ -398,6 +398,16 @@ proxy_GetBoolPref(nsIPrefBranch *aPrefBranch,
         aResult = temp;
 }
 
+static inline bool
+IsHostDomainSocket(const nsACString& aHost)
+{
+#ifdef XP_UNIX
+    return Substring(aHost, 0, 5) == "file:";
+#else
+    return false;
+#endif // XP_UNIX
+}
+
 //----------------------------------------------------------------------------
 
 static const int32_t PROXYCONFIG_DIRECT4X = 3;
@@ -623,7 +633,7 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
         proxy_GetIntPref(prefBranch, PROXY_PREF("ftp_port"), mFTPProxyPort);
 
     if (!pref || !strcmp(pref, PROXY_PREF("socks")))
-        proxy_GetStringPref(prefBranch, PROXY_PREF("socks"), mSOCKSProxyHost);
+        proxy_GetStringPref(prefBranch, PROXY_PREF("socks"), mSOCKSProxyTarget);
 
     if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
         proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
@@ -1871,8 +1881,9 @@ nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
     uint32_t proxyFlags = 0;
 
     if ((flags & RESOLVE_PREFER_SOCKS_PROXY) &&
-        !mSOCKSProxyHost.IsEmpty() && mSOCKSProxyPort > 0) {
-      host = &mSOCKSProxyHost;
+        !mSOCKSProxyTarget.IsEmpty() &&
+        (IsHostDomainSocket(mSOCKSProxyTarget) || mSOCKSProxyPort > 0)) {
+      host = &mSOCKSProxyTarget;
       if (mSOCKSProxyVersion == 4)
           type = kProxyType_SOCKS4;
       else
@@ -1908,8 +1919,9 @@ nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
         type = kProxyType_HTTP;
         port = mFTPProxyPort;
     }
-    else if (!mSOCKSProxyHost.IsEmpty() && mSOCKSProxyPort > 0) {
-        host = &mSOCKSProxyHost;
+    else if (!mSOCKSProxyTarget.IsEmpty() &&
+        (IsHostDomainSocket(mSOCKSProxyTarget) || mSOCKSProxyPort > 0)) {
+        host = &mSOCKSProxyTarget;
         if (mSOCKSProxyVersion == 4)
             type = kProxyType_SOCKS4;
         else
diff --git a/netwerk/base/nsProtocolProxyService.h b/netwerk/base/nsProtocolProxyService.h
index e9813c8..1e1ea7d 100644
--- a/netwerk/base/nsProtocolProxyService.h
+++ b/netwerk/base/nsProtocolProxyService.h
@@ -382,8 +382,9 @@ protected:
 
     nsCString                    mHTTPSProxyHost;
     int32_t                      mHTTPSProxyPort;
-    
-    nsCString                    mSOCKSProxyHost;
+
+    // mSOCKSProxyTarget could be a host or a domain socket path.
+    nsCString                    mSOCKSProxyTarget;
     int32_t                      mSOCKSProxyPort;
     int32_t                      mSOCKSProxyVersion;
     bool                         mSOCKSProxyRemoteDNS;
diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
index 568c700..b26408d 100644
--- a/netwerk/socket/nsSOCKSIOLayer.cpp
+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
@@ -19,8 +19,10 @@
 #include "nsIDNSListener.h"
 #include "nsICancelable.h"
 #include "nsThreadUtils.h"
+#include "nsIURL.h"
 #include "mozilla/Logging.h"
 #include "mozilla/net/DNS.h"
+#include "mozilla/unused.h"
 
 using mozilla::LogLevel;
 using namespace mozilla::net;
@@ -113,6 +115,54 @@ private:
     PRStatus ReadFromSocket(PRFileDesc *fd);
     PRStatus WriteToSocket(PRFileDesc *fd);
 
+    bool IsHostDomainSocket()
+    {
+#ifdef XP_UNIX
+        nsAutoCString proxyHost;
+        mProxy->GetHost(proxyHost);
+        return Substring(proxyHost, 0, 5) == "file:";
+#else
+        return false;
+#endif // XP_UNIX
+    }
+
+    nsresult SetDomainSocketPath(const nsACString& aDomainSocketPath,
+                             NetAddr* aProxyAddr)
+    {
+#ifdef XP_UNIX
+        nsresult rv;
+        MOZ_ASSERT(aProxyAddr);
+
+        nsCOMPtr<nsIURL> url = do_CreateInstance(NS_STANDARDURL_CONTRACTID, &rv);
+        if (NS_WARN_IF(NS_FAILED(rv))) {
+            return rv;
+        }
+
+        if (NS_WARN_IF(NS_FAILED(rv = url->SetSpec(aDomainSocketPath)))) {
+            return rv;
+        }
+
+        nsAutoCString path;
+        if (NS_WARN_IF(NS_FAILED(rv = url->GetPath(path)))) {
+            return rv;
+        }
+
+        if (sizeof(aProxyAddr->local.path) <= path.Length()) {
+            NS_WARNING("domain socket path too long.");
+            return NS_ERROR_FAILURE;
+        }
+
+        aProxyAddr->raw.family = AF_UNIX;
+        strcpy(aProxyAddr->local.path, path.get());
+
+        return NS_OK;
+#else
+        mozilla::Unused << aProxyAddr;
+        mozilla::Unused << aDomainSocketPath;
+        return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+    }
+
 private:
     State     mState;
     uint8_t * mData;
@@ -422,29 +472,40 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd)
         mVersion = 5;
     }
 
+    nsAutoCString proxyHost;
+    mProxy->GetHost(proxyHost);
+
     int32_t proxyPort;
     mProxy->GetPort(&proxyPort);
 
     int32_t addresses = 0;
     do {
-        if (addresses++)
-            mDnsRec->ReportUnusable(proxyPort);
-        
-        rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
-        // No more addresses to try? If so, we'll need to bail
-        if (NS_FAILED(rv)) {
-            nsCString proxyHost;
-            mProxy->GetHost(proxyHost);
-            LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
-                     proxyHost.get()));
-            return PR_FAILURE;
-        }
+        if (IsHostDomainSocket()) {
+            rv = SetDomainSocketPath(proxyHost, &mInternalProxyAddr);
+            if (NS_FAILED(rv)) {
+                LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
+                         proxyHost.get()));
+              return PR_FAILURE;
+            }
+        } else {
+            if (addresses++) {
+                mDnsRec->ReportUnusable(proxyPort);
+            }
+
+            rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
+            // 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",
+                         proxyHost.get()));
+                return PR_FAILURE;
+            }
 
-        if (MOZ_LOG_TEST(gSOCKSLog, LogLevel::Debug)) {
-          char buf[kIPv6CStrBufSize];
-          NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
-          LOGDEBUG(("socks: trying proxy server, %s:%hu",
-                   buf, ntohs(mInternalProxyAddr.inet.port)));
+            if (MOZ_LOG_TEST(gSOCKSLog, LogLevel::Debug)) {
+              char buf[kIPv6CStrBufSize];
+              NetAddrToString(&mInternalProxyAddr, buf, sizeof(buf));
+              LOGDEBUG(("socks: trying proxy server, %s:%hu",
+                       buf, ntohs(mInternalProxyAddr.inet.port)));
+            }
         }
 
         NetAddr proxy = mInternalProxyAddr;
@@ -973,6 +1034,12 @@ nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags)
 
     switch (mState) {
         case SOCKS_INITIAL:
+            if (IsHostDomainSocket()) {
+                mState = SOCKS_DNS_COMPLETE;
+                mLookupStatus = NS_OK;
+                return ConnectToProxy(fd);
+            }
+
             return StartDNS(fd);
         case SOCKS_DNS_IN_PROGRESS:
             PR_SetError(PR_IN_PROGRESS_ERROR, 0);



More information about the tor-commits mailing list