Improve Tor support
authorCryptoManiac <balthazar@yandex.ru>
Mon, 26 Jan 2015 03:02:17 +0000 (06:02 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Mon, 26 Jan 2015 03:02:17 +0000 (06:02 +0300)
Add hidden service name into options and force listening loopback interface if service name is specified.

src/init.cpp
src/net.cpp
src/qt/forms/optionsdialog.ui
src/qt/optionsdialog.cpp
src/qt/optionsmodel.cpp
src/qt/optionsmodel.h

index b934e1c..1c80723 100644 (file)
@@ -244,6 +244,7 @@ std::string HelpMessage()
         "  -proxy=<ip:port>       " + _("Connect through socks proxy") + "\n" +
         "  -socks=<n>             " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
         "  -tor=<ip:port>         " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n"
+        "  -torname=<host.onion>  " + _("Send the specified hidden service name when connecting to Tor nodes (default: none)") + "\n"
         "  -dns                   " + _("Allow DNS lookups for -addnode, -seednode and -connect") + "\n" +
         "  -port=<port>           " + _("Listen for connections on <port> (default: 7777 or testnet: 17777)") + "\n" +
         "  -maxconnections=<n>    " + _("Maintain at most <n> connections to peers (default: 125)") + "\n" +
@@ -697,11 +698,27 @@ bool AppInit2()
 #endif
             if (!IsLimited(NET_IPV4))
                 fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound);
+
         }
         if (!fBound)
             return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
     }
 
+    // If Tor is reachable then listen on loopback interface,
+    //    to allow allow other users reach you through the hidden service
+    if (!IsLimited(NET_TOR) && mapArgs.count("-torname")) {
+        std::string strError;
+        struct in_addr inaddr_loopback;
+        inaddr_loopback.s_addr = htonl(INADDR_LOOPBACK);
+
+#ifdef USE_IPV6
+        if (!BindListenPort(CService(in6addr_loopback, GetListenPort()), strError))
+            return InitError(strError);
+#endif
+        if (!BindListenPort(CService(inaddr_loopback, GetListenPort()), strError))
+            return InitError(strError);
+    }
+
     if (mapArgs.count("-externalip"))
     {
         BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
index 9220122..bba15c4 100644 (file)
@@ -470,8 +470,27 @@ void CNode::PushVersion()
 {
     /// when NTP implemented, change to just nTime = GetAdjustedTime()
     int64_t nTime = (fInbound ? GetAdjustedTime() : GetTime());
-    CAddress addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
-    CAddress addrMe = GetLocalAddress(&addr);
+    CAddress addrYou, addrMe;
+
+    bool fHidden = false;
+    if (addr.IsTor()) {
+        if (mapArgs.count("-torname")) {
+            // Our hidden service address
+            CService addrTorName(mapArgs["-torname"], GetListenPort());
+
+            if (addrTorName.IsValid()) {
+                addrYou = addr;
+                addrMe = CAddress(addrTorName);
+                fHidden = true;
+            }
+        }
+    }
+
+    if (!fHidden) {
+        addrYou = (addr.IsRoutable() && !IsProxy(addr) ? addr : CAddress(CService("0.0.0.0",0)));
+        addrMe = GetLocalAddress(&addr);
+    }
+
     RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
     printf("send version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", PROTOCOL_VERSION, nBestHeight, addrMe.ToString().c_str(), addrYou.ToString().c_str(), addr.ToString().c_str());
     PushMessage("version", PROTOCOL_VERSION, nLocalServices, nTime, addrYou, addrMe,
index d5da8e3..3218a6c 100644 (file)
           <widget class="QValidatedLineEdit" name="torIp">
            <property name="maximumSize">
             <size>
-             <width>130</width>
+             <width>115</width>
              <height>16777215</height>
             </size>
            </property>
         </layout>
        </item>
        <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QLabel" name="torNameLabel">
+           <property name="text">
+            <string>Tor name:</string>
+           </property>
+           <property name="textFormat">
+            <enum>Qt::PlainText</enum>
+           </property>
+           <property name="buddy">
+            <cstring>torName</cstring>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="torName"/>
+         </item>
+         <item>
+          <spacer name="horizontalSpacer_3">
+           <property name="orientation">
+            <enum>Qt::Horizontal</enum>
+           </property>
+           <property name="sizeHint" stdset="0">
+            <size>
+             <width>40</width>
+             <height>20</height>
+            </size>
+           </property>
+          </spacer>
+         </item>
+        </layout>
+       </item>
+       <item>
         <spacer name="verticalSpacer_Network">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
index 671b18c..c964fc3 100644 (file)
@@ -41,6 +41,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
     ui->torPort->setEnabled(false);
     ui->torPort->setValidator(new QIntValidator(1, 65535, this));
     ui->TorOnly->setEnabled(false);
+    ui->torName->setEnabled(false);
 
     ui->socksVersion->setEnabled(false);
     ui->socksVersion->addItem("5", 5);
@@ -56,6 +57,7 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
     connect(ui->connectTor, SIGNAL(toggled(bool)), ui->torIp, SLOT(setEnabled(bool)));
     connect(ui->connectTor, SIGNAL(toggled(bool)), ui->torPort, SLOT(setEnabled(bool)));
     connect(ui->connectTor, SIGNAL(toggled(bool)), ui->TorOnly, SLOT(setEnabled(bool)));
+    connect(ui->connectTor, SIGNAL(toggled(bool)), ui->torName, SLOT(setEnabled(bool)));
     connect(ui->TorOnly, SIGNAL(toggled(bool)), ui->connectSocks, SLOT(setDisabled(bool)));
 
     ui->proxyIp->installEventFilter(this);
@@ -166,6 +168,8 @@ void OptionsDialog::setMapper()
     mapper->addMapping(ui->torIp, OptionsModel::TorIP);
     mapper->addMapping(ui->torPort, OptionsModel::TorPort);
     mapper->addMapping(ui->TorOnly, OptionsModel::TorOnly);
+    mapper->addMapping(ui->torName, OptionsModel::TorName);
+
 
     /* Window */
 #ifndef Q_OS_MAC
index 07a2072..71203f5 100644 (file)
@@ -91,6 +91,14 @@ void OptionsModel::Init()
         SoftSetArg("-tor", settings.value("addrTor").toString().toStdString());
         if (settings.value("fTorOnly").toBool())
             SoftSetArg("-onlynet", "tor");
+
+        if (settings.value("TorName").toString().length() == 22) {
+            std::string strTorName = settings.value("TorName").toString().toStdString();
+
+            CService addrTorName(strTorName, GetListenPort());
+            if (addrTorName.IsValid())
+                SoftSetArg("-torname", strTorName);
+        }
     }
 
     if (settings.contains("detachDB"))
@@ -229,6 +237,8 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
         }
         case TorOnly:
             return settings.value("fTorOnly", false);
+        case TorName:
+            return settings.value("TorName", "");
         case Fee:
             return QVariant(static_cast<qlonglong>(nTransactionFee));
         case DisplayUnit:
@@ -339,6 +349,9 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
             settings.setValue("fTorOnly", value.toBool());
             ApplyTorSettings();
         }
+        case TorName: {
+            settings.setValue("TorName", value.toString());
+        }
         break;
         case Fee:
             nTransactionFee = value.toLongLong();
index 09197f7..6331fac 100644 (file)
@@ -29,6 +29,7 @@ public:
         TorIP,             // QString
         TorPort,           // int
         TorOnly,           // bool
+        TorName,           // QString
         Fee,               // qint64
         DisplayUnit,       // BitcoinUnits::Unit
         DisplayAddresses,  // bool