mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 21:37:17 +01:00
reseed proxy
This commit is contained in:
parent
5109d40d8e
commit
65db96e663
|
@ -179,6 +179,7 @@ namespace config {
|
||||||
("reseed.floodfill", value<std::string>()->default_value(""), "Path to router info of floodfill to reseed from")
|
("reseed.floodfill", value<std::string>()->default_value(""), "Path to router info of floodfill to reseed from")
|
||||||
("reseed.file", value<std::string>()->default_value(""), "Path to local .su3 file or HTTPS URL to reseed from")
|
("reseed.file", value<std::string>()->default_value(""), "Path to local .su3 file or HTTPS URL to reseed from")
|
||||||
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
("reseed.zipfile", value<std::string>()->default_value(""), "Path to local .zip file to reseed from")
|
||||||
|
("reseed.proxy", value<std::string>()->default_value(""), "url for reseed proxy, supports http/socks")
|
||||||
("reseed.urls", value<std::string>()->default_value(
|
("reseed.urls", value<std::string>()->default_value(
|
||||||
"https://reseed.i2p-projekt.de/,"
|
"https://reseed.i2p-projekt.de/,"
|
||||||
"https://i2p.mooo.com/netDb/,"
|
"https://i2p.mooo.com/netDb/,"
|
||||||
|
|
|
@ -1247,7 +1247,7 @@ namespace transport
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
buff[4] = (uint8_t) addrsize;
|
buff[4] = (uint8_t) addrsize;
|
||||||
memcpy(buff+4, host.c_str(), addrsize);
|
memcpy(buff+5, host.c_str(), addrsize);
|
||||||
}
|
}
|
||||||
htobe16buf(buff+sz, port);
|
htobe16buf(buff+sz, port);
|
||||||
sz += 2;
|
sz += 2;
|
||||||
|
@ -1259,7 +1259,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, sz), [=](const boost::system::error_code & e, std::size_t transferred) {
|
boost::asio::async_read(conn->GetSocket(), boost::asio::buffer(readbuff, 10), [=](const boost::system::error_code & e, std::size_t transferred) {
|
||||||
if(e)
|
if(e)
|
||||||
{
|
{
|
||||||
LogPrint(eLogError, "NTCP: socks proxy read error ", e.message());
|
LogPrint(eLogError, "NTCP: socks proxy read error ", e.message());
|
||||||
|
|
|
@ -489,6 +489,27 @@ namespace data
|
||||||
|
|
||||||
std::string Reseeder::HttpsRequest (const std::string& address)
|
std::string Reseeder::HttpsRequest (const std::string& address)
|
||||||
{
|
{
|
||||||
|
i2p::http::URL proxyUrl;
|
||||||
|
std::string proxy; i2p::config::GetOption("reseed.proxy", proxy);
|
||||||
|
// check for proxy url
|
||||||
|
if(proxy.size()) {
|
||||||
|
// parse
|
||||||
|
if(proxyUrl.parse(proxy)) {
|
||||||
|
if (proxyUrl.schema == "http" && !proxyUrl.port) {
|
||||||
|
proxyUrl.port = 80;
|
||||||
|
} else if (proxyUrl.schema == "socks" && !proxyUrl.port) {
|
||||||
|
proxyUrl.port = 1080;
|
||||||
|
}
|
||||||
|
// check for valid proxy url schema
|
||||||
|
if (proxyUrl.schema != "http" && proxyUrl.schema != "socks") {
|
||||||
|
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogPrint(eLogError, "Reseed: bad proxy url: ", proxy);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
i2p::http::URL url;
|
i2p::http::URL url;
|
||||||
if (!url.parse(address)) {
|
if (!url.parse(address)) {
|
||||||
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
LogPrint(eLogError, "Reseed: failed to parse url: ", address);
|
||||||
|
@ -500,15 +521,135 @@ namespace data
|
||||||
|
|
||||||
boost::asio::io_service service;
|
boost::asio::io_service service;
|
||||||
boost::system::error_code ecode;
|
boost::system::error_code ecode;
|
||||||
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
|
||||||
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
|
||||||
if (!ecode)
|
|
||||||
{
|
|
||||||
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
|
boost::asio::ssl::context ctx(service, boost::asio::ssl::context::sslv23);
|
||||||
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
ctx.set_verify_mode(boost::asio::ssl::context::verify_none);
|
||||||
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> s(service, ctx);
|
||||||
|
|
||||||
|
if(proxyUrl.schema.size())
|
||||||
|
{
|
||||||
|
// proxy connection
|
||||||
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
|
boost::asio::ip::tcp::resolver::query (proxyUrl.host, std::to_string(proxyUrl.port)), ecode);
|
||||||
|
if(!ecode)
|
||||||
|
{
|
||||||
s.lowest_layer().connect(*it, ecode);
|
s.lowest_layer().connect(*it, ecode);
|
||||||
if(!ecode)
|
if(!ecode)
|
||||||
|
{
|
||||||
|
auto & sock = s.next_layer();
|
||||||
|
if(proxyUrl.schema == "http")
|
||||||
|
{
|
||||||
|
i2p::http::HTTPReq proxyReq;
|
||||||
|
i2p::http::HTTPRes proxyRes;
|
||||||
|
proxyReq.method = "CONNECT";
|
||||||
|
proxyReq.version = "HTTP/1.1";
|
||||||
|
proxyReq.uri = url.host + ":" + std::to_string(url.port);
|
||||||
|
|
||||||
|
boost::asio::streambuf writebuf, readbuf;
|
||||||
|
|
||||||
|
std::ostream out(&writebuf);
|
||||||
|
out << proxyReq.to_string();
|
||||||
|
|
||||||
|
boost::asio::write(sock, writebuf.data(), boost::asio::transfer_all(), ecode);
|
||||||
|
if (ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT write error: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
boost::asio::read_until(sock, readbuf, "\r\n\r\n", ecode);
|
||||||
|
if (ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT read error: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(proxyRes.parse(boost::asio::buffer_cast<const char *>(readbuf.data()), readbuf.size()) <= 0)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT malformed reply");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(proxyRes.code != 200)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: HTTP CONNECT got bad status: ", proxyRes.code);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// assume socks if not http, is checked before this for other types
|
||||||
|
// TODO: support username/password auth etc
|
||||||
|
uint8_t hs_writebuf[3] = {0x05, 0x01, 0x00};
|
||||||
|
uint8_t hs_readbuf[2];
|
||||||
|
boost::asio::write(sock, boost::asio::buffer(hs_writebuf, 3), boost::asio::transfer_all(), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake write failed: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
boost::asio::read(sock, boost::asio::buffer(hs_readbuf, 2), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake read failed: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
size_t sz = 0;
|
||||||
|
uint8_t buf[256];
|
||||||
|
|
||||||
|
buf[0] = 0x05;
|
||||||
|
buf[1] = 0x01;
|
||||||
|
buf[2] = 0x00;
|
||||||
|
buf[3] = 0x03;
|
||||||
|
sz += 4;
|
||||||
|
size_t hostsz = url.host.size();
|
||||||
|
if(1 + 2 + hostsz + sz > sizeof(buf))
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed, hostname too big: ", url.host);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
buf[4] = (uint8_t) hostsz;
|
||||||
|
memcpy(buf+5, url.host.c_str(), hostsz);
|
||||||
|
sz += hostsz + 1;
|
||||||
|
htobe16buf(buf+sz, url.port);
|
||||||
|
sz += 2;
|
||||||
|
boost::asio::write(sock, boost::asio::buffer(buf, sz), boost::asio::transfer_all(), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed writing: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
boost::asio::read(sock, boost::asio::buffer(buf, 10), ecode);
|
||||||
|
if(ecode)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake failed reading: ", ecode.message());
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if(buf[1] != 0x00)
|
||||||
|
{
|
||||||
|
sock.close();
|
||||||
|
LogPrint(eLogError, "Reseed: SOCKS handshake bad reply code: ", std::to_string(buf[1]));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// direct connection
|
||||||
|
auto it = boost::asio::ip::tcp::resolver(service).resolve (
|
||||||
|
boost::asio::ip::tcp::resolver::query (url.host, std::to_string(url.port)), ecode);
|
||||||
|
if(!ecode)
|
||||||
|
s.lowest_layer().connect (*it, ecode);
|
||||||
|
}
|
||||||
|
if (!ecode)
|
||||||
{
|
{
|
||||||
SSL_set_tlsext_host_name(s.native_handle(), url.host.c_str ());
|
SSL_set_tlsext_host_name(s.native_handle(), url.host.c_str ());
|
||||||
s.handshake (boost::asio::ssl::stream_base::client, ecode);
|
s.handshake (boost::asio::ssl::stream_base::client, ecode);
|
||||||
|
@ -557,9 +698,6 @@ namespace data
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LogPrint (eLogError, "Reseed: Couldn't connect to ", url.host, ": ", ecode.message ());
|
LogPrint (eLogError, "Reseed: Couldn't connect to ", url.host, ": ", ecode.message ());
|
||||||
}
|
|
||||||
else
|
|
||||||
LogPrint (eLogError, "Reseed: Couldn't resolve address ", url.host, ": ", ecode.message ());
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue