Skip to content
Snippets Groups Projects
Unverified Commit 60d43319 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

dht_proxy_client: fix getPublicAdresss

Retrieve all public ips (Ipv6 + v4). Has to resolve all proxy
address (so two get requests to get all ips)
parent 8c85f84b
No related branches found
No related tags found
No related merge requests found
...@@ -263,7 +263,7 @@ private: ...@@ -263,7 +263,7 @@ private:
* @return the JSON returned by the proxy * @return the JSON returned by the proxy
*/ */
void getProxyInfos(); void getProxyInfos();
void onProxyInfos(const Json::Value& val); void onProxyInfos(const Json::Value& val, const sa_family_t& family);
SockAddr parsePublicAddress(const Json::Value& val); SockAddr parsePublicAddress(const Json::Value& val);
void opFailed(); void opFailed();
...@@ -292,7 +292,8 @@ private: ...@@ -292,7 +292,8 @@ private:
NodeStatus statusIpv6_ {NodeStatus::Disconnected}; NodeStatus statusIpv6_ {NodeStatus::Disconnected};
NodeStats stats4_ {}; NodeStats stats4_ {};
NodeStats stats6_ {}; NodeStats stats6_ {};
SockAddr publicAddress_; SockAddr publicAddressV4_;
SockAddr publicAddressV6_;
InfoHash myid {}; InfoHash myid {};
......
...@@ -364,14 +364,32 @@ DhtProxyClient::getProxyInfos() ...@@ -364,14 +364,32 @@ DhtProxyClient::getProxyInfos()
statusIpv6_ = NodeStatus::Connecting; statusIpv6_ = NodeStatus::Connecting;
} }
restbed::Uri uri(HTTP_PROTO + serverHost_ + "/"); // A node can have a Ipv4 and a Ipv6. So, we need to retrieve all public ips
auto req = std::make_shared<restbed::Request>(uri); std::string host, service;
auto serviceMarker = serverHost_.find(':');
if (serviceMarker != std::string::npos) {
host = serverHost_.substr(0, serviceMarker - 1);
service = serverHost_.substr(serviceMarker + 1);
} else {
host = serverHost_;
}
auto resolved_proxies = SockAddr::resolve(host, service);
auto serverHost = serverHost_;
// Try to contact the proxy and set the status to connected when done. // Try to contact the proxy and set the status to connected when done.
// will change the connectivity status // will change the connectivity status
statusThread_ = std::thread([this, req]{ statusThread_ = std::thread([this, resolved_proxies, serverHost]{
for (const auto& resolved_proxy: resolved_proxies) {
auto server = resolved_proxy.toString();
if (resolved_proxy.getFamily() == AF_INET6) {
// HACK restbed seems to not correctly handle directly http://[ipv6]
// See https://github.com/Corvusoft/restbed/issues/290.
server = serverHost;
}
restbed::Uri uri(HTTP_PROTO + server + "/");
auto req = std::make_shared<restbed::Request>(uri);
restbed::Http::async(req, restbed::Http::async(req,
[this](const std::shared_ptr<restbed::Request>&, [this, resolved_proxy](const std::shared_ptr<restbed::Request>&,
const std::shared_ptr<restbed::Response>& reply) { const std::shared_ptr<restbed::Response>& reply) {
auto code = reply->get_status_code(); auto code = reply->get_status_code();
Json::Value proxyInfos; Json::Value proxyInfos;
...@@ -387,16 +405,17 @@ DhtProxyClient::getProxyInfos() ...@@ -387,16 +405,17 @@ DhtProxyClient::getProxyInfos()
reader->parse(body.data(), body.data() + body.size(), &proxyInfos, &err); reader->parse(body.data(), body.data() + body.size(), &proxyInfos, &err);
} catch (...) { } catch (...) {
} }
onProxyInfos(proxyInfos, resolved_proxy.getFamily());
} }
onProxyInfos(proxyInfos);
ongoingStatusUpdate_.clear(); ongoingStatusUpdate_.clear();
}); });
}
}); });
statusThread_.detach(); statusThread_.detach();
} }
void void
DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos) DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos, const sa_family_t& family)
{ {
std::lock_guard<std::mutex> l(lockCurrentProxyInfos_); std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
...@@ -421,7 +440,10 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos) ...@@ -421,7 +440,10 @@ DhtProxyClient::onProxyInfos(const Json::Value& proxyInfos)
else else
statusIpv6_ = NodeStatus::Disconnected; statusIpv6_ = NodeStatus::Disconnected;
publicAddress_ = parsePublicAddress(proxyInfos["public_ip"]); if (family == AF_INET)
publicAddressV4_ = parsePublicAddress(proxyInfos["public_ip"]);
else if (family == AF_INET6)
publicAddressV6_ = parsePublicAddress(proxyInfos["public_ip"]);
} catch (...) {} } catch (...) {}
auto newStatus = std::max(statusIpv4_, statusIpv6_); auto newStatus = std::max(statusIpv4_, statusIpv6_);
...@@ -443,9 +465,9 @@ DhtProxyClient::parsePublicAddress(const Json::Value& val) ...@@ -443,9 +465,9 @@ DhtProxyClient::parsePublicAddress(const Json::Value& val)
{ {
auto public_ip = val.asString(); auto public_ip = val.asString();
auto endIp = public_ip.find_last_of(':'); auto endIp = public_ip.find_last_of(':');
std::string service = public_ip.substr(endIp + 1); auto marker = (public_ip.size() > 0 && public_ip[0] == '[') ? 1 : 0;
std::string address = public_ip.substr(0, endIp - 1); std::string address = public_ip.substr(marker, endIp - marker * 2);
auto sa = SockAddr::resolve(address, service); auto sa = SockAddr::resolve(address);
if (sa.empty()) return {}; if (sa.empty()) return {};
return sa.front().getMappedIPv4(); return sa.front().getMappedIPv4();
} }
...@@ -454,8 +476,10 @@ std::vector<SockAddr> ...@@ -454,8 +476,10 @@ std::vector<SockAddr>
DhtProxyClient::getPublicAddress(sa_family_t family) DhtProxyClient::getPublicAddress(sa_family_t family)
{ {
std::lock_guard<std::mutex> l(lockCurrentProxyInfos_); std::lock_guard<std::mutex> l(lockCurrentProxyInfos_);
if (not publicAddress_) return {}; std::vector<SockAddr> result;
return publicAddress_.getFamily() == family ? std::vector<SockAddr>{publicAddress_} : std::vector<SockAddr>{}; if (publicAddressV6_ && family != AF_INET) result.emplace_back(publicAddressV6_);
if (publicAddressV4_ && family != AF_INET6) result.emplace_back(publicAddressV4_);
return result;
} }
size_t size_t
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment