mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
merge bitcoin#15423: Query Tor for correct -onion configuration
This commit is contained in:
parent
74dceb3c5c
commit
092a11e2d1
@ -48,6 +48,7 @@ static const float RECONNECT_TIMEOUT_EXP = 1.5;
|
||||
* this is belt-and-suspenders sanity limit to prevent memory exhaustion.
|
||||
*/
|
||||
static const int MAX_LINE_LENGTH = 100000;
|
||||
static const uint16_t DEFAULT_TOR_SOCKS_PORT = 9050;
|
||||
|
||||
/****** Low-level TorControlConnection ********/
|
||||
|
||||
@ -333,6 +334,73 @@ TorController::~TorController()
|
||||
}
|
||||
}
|
||||
|
||||
void TorController::get_socks_cb(TorControlConnection& _conn, const TorControlReply& reply)
|
||||
{
|
||||
// NOTE: We can only get here if -onion is unset
|
||||
std::string socks_location;
|
||||
if (reply.code == 250) {
|
||||
for (const auto& line : reply.lines) {
|
||||
if (0 == line.compare(0, 20, "net/listeners/socks=")) {
|
||||
const std::string port_list_str = line.substr(20);
|
||||
std::vector<std::string> port_list = SplitString(port_list_str, ' ');
|
||||
|
||||
for (auto& portstr : port_list) {
|
||||
if (portstr.empty()) continue;
|
||||
if ((portstr[0] == '"' || portstr[0] == '\'') && portstr.size() >= 2 && (*portstr.rbegin() == portstr[0])) {
|
||||
portstr = portstr.substr(1, portstr.size() - 2);
|
||||
if (portstr.empty()) continue;
|
||||
}
|
||||
socks_location = portstr;
|
||||
if (0 == portstr.compare(0, 10, "127.0.0.1:")) {
|
||||
// Prefer localhost - ignore other ports
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!socks_location.empty()) {
|
||||
LogPrint(BCLog::TOR, "tor: Get SOCKS port command yielded %s\n", socks_location);
|
||||
} else {
|
||||
LogPrintf("tor: Get SOCKS port command returned nothing\n");
|
||||
}
|
||||
} else if (reply.code == 510) { // 510 Unrecognized command
|
||||
LogPrintf("tor: Get SOCKS port command failed with unrecognized command (You probably should upgrade Tor)\n");
|
||||
} else {
|
||||
LogPrintf("tor: Get SOCKS port command failed; error code %d\n", reply.code);
|
||||
}
|
||||
|
||||
CService resolved;
|
||||
Assume(!resolved.IsValid());
|
||||
if (!socks_location.empty()) {
|
||||
resolved = LookupNumeric(socks_location, DEFAULT_TOR_SOCKS_PORT);
|
||||
}
|
||||
if (!resolved.IsValid()) {
|
||||
// Fallback to old behaviour
|
||||
resolved = LookupNumeric("127.0.0.1", DEFAULT_TOR_SOCKS_PORT);
|
||||
}
|
||||
|
||||
Assume(resolved.IsValid());
|
||||
LogPrint(BCLog::TOR, "tor: Configuring onion proxy for %s\n", resolved.ToStringAddrPort());
|
||||
Proxy addrOnion = Proxy(resolved, true);
|
||||
SetProxy(NET_ONION, addrOnion);
|
||||
|
||||
const auto onlynets = gArgs.GetArgs("-onlynet");
|
||||
|
||||
const bool onion_allowed_by_onlynet{
|
||||
!gArgs.IsArgSet("-onlynet") ||
|
||||
std::any_of(onlynets.begin(), onlynets.end(), [](const auto& n) {
|
||||
return ParseNetwork(n) == NET_ONION;
|
||||
})};
|
||||
|
||||
if (onion_allowed_by_onlynet) {
|
||||
// If NET_ONION is reachable, then the below is a noop.
|
||||
//
|
||||
// If NET_ONION is not reachable, then none of -proxy or -onion was given.
|
||||
// Since we are here, then -torcontrol and -torpassword were given.
|
||||
SetReachable(NET_ONION, true);
|
||||
}
|
||||
}
|
||||
|
||||
void TorController::add_onion_cb(TorControlConnection& _conn, const TorControlReply& reply)
|
||||
{
|
||||
if (reply.code == 250) {
|
||||
@ -376,25 +444,7 @@ void TorController::auth_cb(TorControlConnection& _conn, const TorControlReply&
|
||||
// Now that we know Tor is running setup the proxy for onion addresses
|
||||
// if -onion isn't set to something else.
|
||||
if (gArgs.GetArg("-onion", "") == "") {
|
||||
CService resolved(LookupNumeric("127.0.0.1", 9050));
|
||||
Proxy addrOnion = Proxy(resolved, true);
|
||||
SetProxy(NET_ONION, addrOnion);
|
||||
|
||||
const auto onlynets = gArgs.GetArgs("-onlynet");
|
||||
|
||||
const bool onion_allowed_by_onlynet{
|
||||
!gArgs.IsArgSet("-onlynet") ||
|
||||
std::any_of(onlynets.begin(), onlynets.end(), [](const auto& n) {
|
||||
return ParseNetwork(n) == NET_ONION;
|
||||
})};
|
||||
|
||||
if (onion_allowed_by_onlynet) {
|
||||
// If NET_ONION is reachable, then the below is a noop.
|
||||
//
|
||||
// If NET_ONION is not reachable, then none of -proxy or -onion was given.
|
||||
// Since we are here, then -torcontrol and -torpassword were given.
|
||||
SetReachable(NET_ONION, true);
|
||||
}
|
||||
_conn.Command("GETINFO net/listeners/socks", std::bind(&TorController::get_socks_cb, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
// Finally - now create the service
|
||||
|
@ -140,6 +140,8 @@ private:
|
||||
std::vector<uint8_t> clientNonce;
|
||||
|
||||
public:
|
||||
/** Callback for GETINFO net/listeners/socks result */
|
||||
void get_socks_cb(TorControlConnection& conn, const TorControlReply& reply);
|
||||
/** Callback for ADD_ONION result */
|
||||
void add_onion_cb(TorControlConnection& conn, const TorControlReply& reply);
|
||||
/** Callback for AUTHENTICATE result */
|
||||
|
Loading…
Reference in New Issue
Block a user