mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 04:04:16 +00:00
[reseed] support domains in yggdrasil reseeder, fix IPv6 URL host parsing
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
58ef08310d
commit
7b35c793f3
@ -93,15 +93,18 @@ namespace http
|
|||||||
std::size_t pos_c = 0; /* < work position */
|
std::size_t pos_c = 0; /* < work position */
|
||||||
if(url.at(0) != '/' || pos_p > 0) {
|
if(url.at(0) != '/' || pos_p > 0) {
|
||||||
std::size_t pos_s = 0;
|
std::size_t pos_s = 0;
|
||||||
|
|
||||||
/* schema */
|
/* schema */
|
||||||
pos_c = url.find("://");
|
pos_c = url.find("://");
|
||||||
if (pos_c != std::string::npos) {
|
if (pos_c != std::string::npos) {
|
||||||
schema = url.substr(0, pos_c);
|
schema = url.substr(0, pos_c);
|
||||||
pos_p = pos_c + 3;
|
pos_p = pos_c + 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* user[:pass] */
|
/* user[:pass] */
|
||||||
pos_s = url.find('/', pos_p); /* find first slash */
|
pos_s = url.find('/', pos_p); /* find first slash */
|
||||||
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */
|
pos_c = url.find('@', pos_p); /* find end of 'user' or 'user:pass' part */
|
||||||
|
|
||||||
if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
|
if (pos_c != std::string::npos && (pos_s == std::string::npos || pos_s > pos_c)) {
|
||||||
std::size_t delim = url.find(':', pos_p);
|
std::size_t delim = url.find(':', pos_p);
|
||||||
if (delim && delim != std::string::npos && delim < pos_c) {
|
if (delim && delim != std::string::npos && delim < pos_c) {
|
||||||
@ -113,21 +116,28 @@ namespace http
|
|||||||
}
|
}
|
||||||
pos_p = pos_c + 1;
|
pos_p = pos_c + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* hostname[:port][/path] */
|
/* hostname[:port][/path] */
|
||||||
if (url[pos_p] == '[') // ipv6
|
if (url.at(pos_p) == '[') // ipv6
|
||||||
{
|
{
|
||||||
auto pos_b = url.find(']', pos_p);
|
auto pos_b = url.find(']', pos_p);
|
||||||
if (pos_b == std::string::npos) return false;
|
if (pos_b == std::string::npos) return false;
|
||||||
|
ipv6 = true;
|
||||||
pos_c = url.find_first_of(":/", pos_b);
|
pos_c = url.find_first_of(":/", pos_b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pos_c = url.find_first_of(":/", pos_p);
|
pos_c = url.find_first_of(":/", pos_p);
|
||||||
|
|
||||||
if (pos_c == std::string::npos) {
|
if (pos_c == std::string::npos) {
|
||||||
/* only hostname, without post and path */
|
/* only hostname, without post and path */
|
||||||
host = url.substr(pos_p, std::string::npos);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, url.length() - 1) :
|
||||||
|
url.substr(pos_p, std::string::npos);
|
||||||
return true;
|
return true;
|
||||||
} else if (url.at(pos_c) == ':') {
|
} else if (url.at(pos_c) == ':') {
|
||||||
host = url.substr(pos_p, pos_c - pos_p);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, pos_c - pos_p - 2) :
|
||||||
|
url.substr(pos_p, pos_c - pos_p);
|
||||||
/* port[/path] */
|
/* port[/path] */
|
||||||
pos_p = pos_c + 1;
|
pos_p = pos_c + 1;
|
||||||
pos_c = url.find('/', pos_p);
|
pos_c = url.find('/', pos_p);
|
||||||
@ -147,7 +157,9 @@ namespace http
|
|||||||
pos_p = pos_c;
|
pos_p = pos_c;
|
||||||
} else {
|
} else {
|
||||||
/* start of path part found */
|
/* start of path part found */
|
||||||
host = url.substr(pos_p, pos_c - pos_p);
|
host = ipv6 ?
|
||||||
|
url.substr(pos_p + 1, pos_c - pos_p - 2) :
|
||||||
|
url.substr(pos_p, pos_c - pos_p);
|
||||||
pos_p = pos_c;
|
pos_p = pos_c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,10 +224,18 @@ namespace http
|
|||||||
} else if (user != "") {
|
} else if (user != "") {
|
||||||
out += user + "@";
|
out += user + "@";
|
||||||
}
|
}
|
||||||
if (port) {
|
if (ipv6) {
|
||||||
out += host + ":" + std::to_string(port);
|
if (port) {
|
||||||
|
out += "[" + host + "]:" + std::to_string(port);
|
||||||
|
} else {
|
||||||
|
out += "[" + host + "]";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
out += host;
|
if (port) {
|
||||||
|
out += host + ":" + std::to_string(port);
|
||||||
|
} else {
|
||||||
|
out += host;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out += path;
|
out += path;
|
||||||
|
@ -36,8 +36,9 @@ namespace http
|
|||||||
bool hasquery;
|
bool hasquery;
|
||||||
std::string query;
|
std::string query;
|
||||||
std::string frag;
|
std::string frag;
|
||||||
|
bool ipv6;
|
||||||
|
|
||||||
URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag("") {};
|
URL(): schema(""), user(""), pass(""), host(""), port(0), path(""), hasquery(false), query(""), frag(""), ipv6(false) {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Tries to parse url from string
|
* @brief Tries to parse url from string
|
||||||
|
@ -703,6 +703,7 @@ namespace data
|
|||||||
s.lowest_layer().connect (ep, ecode);
|
s.lowest_layer().connect (ep, ecode);
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Resolved to ", ep.address ());
|
||||||
connected = true;
|
connected = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -790,17 +791,45 @@ namespace data
|
|||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
|
boost::asio::ip::tcp::socket s(service, boost::asio::ip::tcp::v6());
|
||||||
|
|
||||||
if (url.host.length () < 2) return ""; // assume []
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
auto host = url.host.substr (1, url.host.length () - 2);
|
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
||||||
LogPrint (eLogDebug, "Reseed: Connecting to Yggdrasil ", url.host, ":", url.port);
|
|
||||||
s.connect (boost::asio::ip::tcp::endpoint (boost::asio::ip::address_v6::from_string (host), url.port), ecode);
|
|
||||||
if (!ecode)
|
if (!ecode)
|
||||||
{
|
{
|
||||||
LogPrint (eLogDebug, "Reseed: Connected to Yggdrasil ", url.host, ":", url.port);
|
bool connected = false;
|
||||||
|
boost::asio::ip::tcp::resolver::iterator end;
|
||||||
|
while (it != end)
|
||||||
|
{
|
||||||
|
boost::asio::ip::tcp::endpoint ep = *it;
|
||||||
|
if (
|
||||||
|
i2p::util::net::IsYggdrasilAddress (ep.address ()) &&
|
||||||
|
i2p::context.SupportsMesh ()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Yggdrasil: Resolved to ", ep.address ());
|
||||||
|
s.connect (ep, ecode);
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
connected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
if (!connected)
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "Reseed: Yggdrasil: Failed to connect to ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ecode)
|
||||||
|
{
|
||||||
|
LogPrint (eLogDebug, "Reseed: Yggdrasil: Connected to ", url.host, ":", url.port);
|
||||||
return ReseedRequest (s, url.to_string());
|
return ReseedRequest (s, url.to_string());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Couldn't connect to Yggdrasil ", url.host, ": ", ecode.message ());
|
LogPrint (eLogError, "Reseed: Yggdrasil: Couldn't connect to ", url.host, ": ", ecode.message ());
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user