From 64f815a4a18993c77629234a4d09dd2adfedaec7 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Mon, 26 Jan 2015 06:02:17 +0300 Subject: [PATCH] Improve Tor support Add hidden service name into options and force listening loopback interface if service name is specified. --- src/init.cpp | 17 +++++++++++++++++ src/net.cpp | 23 +++++++++++++++++++++-- src/qt/forms/optionsdialog.ui | 35 ++++++++++++++++++++++++++++++++++- src/qt/optionsdialog.cpp | 4 ++++ src/qt/optionsmodel.cpp | 13 +++++++++++++ src/qt/optionsmodel.h | 1 + 6 files changed, 90 insertions(+), 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b934e1c..1c80723 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -244,6 +244,7 @@ std::string HelpMessage() " -proxy= " + _("Connect through socks proxy") + "\n" + " -socks= " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + " -tor= " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n" + " -torname= " + _("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= " + _("Listen for connections on (default: 7777 or testnet: 17777)") + "\n" + " -maxconnections= " + _("Maintain at most 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"]) { diff --git a/src/net.cpp b/src/net.cpp index 9220122..bba15c4 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -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, diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index d5da8e3..3218a6c 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -258,7 +258,7 @@ - 130 + 115 16777215 @@ -304,6 +304,39 @@ + + + + + Tor name: + + + Qt::PlainText + + + torName + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + Qt::Vertical diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 671b18c..c964fc3 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -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 diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 07a2072..71203f5 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -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(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(); diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index 09197f7..6331fac 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -29,6 +29,7 @@ public: TorIP, // QString TorPort, // int TorOnly, // bool + TorName, // QString Fee, // qint64 DisplayUnit, // BitcoinUnits::Unit DisplayAddresses, // bool -- 1.7.1