Add hidden service name into options and force listening loopback interface if service name is specified.
" -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" +
#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"]) {
{
/// 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,
<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>
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);
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);
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
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"))
}
case TorOnly:
return settings.value("fTorOnly", false);
+ case TorName:
+ return settings.value("TorName", "");
case Fee:
return QVariant(static_cast<qlonglong>(nTransactionFee));
case DisplayUnit:
settings.setValue("fTorOnly", value.toBool());
ApplyTorSettings();
}
+ case TorName: {
+ settings.setValue("TorName", value.toString());
+ }
break;
case Fee:
nTransactionFee = value.toLongLong();
TorIP, // QString
TorPort, // int
TorOnly, // bool
+ TorName, // QString
Fee, // qint64
DisplayUnit, // BitcoinUnits::Unit
DisplayAddresses, // bool